2016-07-14 14 views
1

編集可能なテキストフィールドがドットマトリックスプリンタ用の事前印刷済みフォームの上に表示される「塗りつぶしフォーム」を実装しようとしています。 (C#とWindows Formsと.Net 2.0を使用して)私の最初のアイデアは、Windowsフォームの背景としてイメージを使用することでしたが、スクロールしてもひどく見え、コンテンツも正しくスクロールできませんでした。コントロールがレイヤ化されているときに、Windowsフォームで透明コントロールを作成する方法

次に、ウィンドウの境界をオーバーフローする(スクロールするための)パネルを持つ固定サイズのウィンドウを作成しました。パネルにPictureBoxを追加し、その上にテキストボックスを追加しました。これは、テキストボックスが透明をサポートしていないことを除いて、うまくいきます。そのため、テキストボックスを透明にするいくつかの方法を試しました。 1つのアプローチは、奇妙な背景色と透過キーを使用することでした。もう一つは、以下のリンクで説明し、透明性を可能に派生クラスを作成することでした。私が知るようになってきているようので

Transparency for windows forms textbox

TextBox with a Transparent Background

をどちらの方法では、Windowsの「透明性」、作品フォームは、ウィンドウの背景がコントロールの背景にペイントされることを意味します。 PictureBoxはウィンドウの背景とTextBoxの間に配置されているため、TextBoxが透過的ではなく、単にウィンドウの背景色と同じ背景色を持つように見えます。透明性のキーアプローチを使用すると、アプリケーション全体が透過的になり、バックグラウンドでVisual Studioを見ることができます。これは私が望むものではありません。今度はTextBoxから派生し、OnPaintまたはOnPaintBackgroundをオーバーライドしてPictureBoxイメージの適切な部分をコントロールの背景にペイントして、次のリンクに示すように透明度の錯覚を与えるクラスを実装しようとしています:

How to create a transparent control which works when on top of other controls?

まず第一に、私はそれを働かせることができません(私はいろいろ試してみましたが、完全に黒色のコントロール、または標準のラベルバックグラウンドを取得する)、そして第二にDrawToBitmapから断続的なArgumentExceptionsメソッドには、「追加情報:targetBounds」という謎のメッセージがあります。 MSDNの次のリンクに基づいて、私はこれがビットマップが大きすぎるためだと信じています。どちらの場合でも、フォームイメージ全体をキャプチャするのは非効率的です。ここで

https://msdn.microsoft.com/en-us/library/system.windows.forms.control.drawtobitmap(v=vs.100).aspx

私の最新の試みです。誰かがOnPaintBackgroundの実装を手伝ってもらうか、別の方法を提案できますか?前もって感謝します!

public partial class TransparentTextbox : TextBox 
{ 
    public TransparentTextbox() 
    { 
     InitializeComponent(); 
     SetStyle(ControlStyles.OptimizedDoubleBuffer | 
        ControlStyles.AllPaintingInWmPaint | 
        ControlStyles.ResizeRedraw | 
        ControlStyles.UserPaint, true); 
    } 

    protected override void OnPaintBackground(PaintEventArgs e) 
    { 
     //base.OnPaintBackground(e); // not sure whether I need this 
     if (Parent != null) 
     { 
      foreach (Control c in Parent.Controls) 
      { 
       if (c.GetType() == typeof(PictureBox)) 
       { 
        PictureBox formImg = (PictureBox)c; 
        Bitmap bitmap = new Bitmap(formImg.Width, formImg.Height); 
        formImg.DrawToBitmap(bitmap, formImg.Bounds); 
        e.Graphics.DrawImage(bitmap, -Left, -Top); 

        break; 
       } 
      } 

      Debug.WriteLine(Name + " didn't find the PictureBox."); 
     } 
    } 
} 

注:これは複製としてタグ付けされていますが、私の元の投稿の「複製の質問」を参照して、なぜ機能していないのかを説明しました。このソリューションは、TextBoxが直接ウィンドウ上に置かれている場合にのみ機能します。 - 別のコントロール(PanelやPictureBoxなど)がウィンドウとTextBoxの間にある場合、.NetはTextBoxの背景にウィンドウの背景を描画し、透明ではありません。

+1

Windowsフォームの標準TextBoxではこれが可能ではないと思います。サードパーティのキットを使用することをお勧めします(お勧めできます)、Infragisticsは、背景イメージと原点を使用して問題を解決します。 http://www.infragistics.com/community/forums/t/1324.aspx – Mangist

+1

[Alpha Blended(Transparent Capable)TextBoxとRichTextBox](http://www.codeproject.com/Articles)の記事を見てください。/AlphaBlendTextBox/AlphaBlendTextBox/AlphaBlendTextBox/13197/AlphaBlendTextBox)は、 A透明 - 半透明 - テキストボード) –

+0

これは、Windowsフォームの一部のサードパーティのコンポーネントでほぼ解決できる制限でした。しかし、それは単純なWinformsプロジェクトに1トンの重さと参照を追加します。質問からWPFに切り替えるのですか?このようなものは、非常に受け入れやすいでしょう。 –

答えて

-1

私は最終的にこれの底になったと思います。私はクラスにビットマップ変数を追加しました。テキストボックスをインスタンス化するときに、コントロールの背後にあるフォームイメージの部分だけを含むように設定しています。次に、OnPaintBackgroundをオーバーロードしてビットマップを表示し、OnPaintをオーバーロードして手動でテキスト文字列を描画します。以下は、私のTransparentTextboxクラスの更新版です:

public partial class TransparentTextbox : TextBox 
{ 
    public Bitmap BgBitmap { get; set; } 

    public TransparentTextbox() 
    { 
     InitializeComponent(); 
     SetStyle(ControlStyles.OptimizedDoubleBuffer | 
        ControlStyles.AllPaintingInWmPaint | 
        ControlStyles.ResizeRedraw | 
        ControlStyles.UserPaint, true); 
    } 

    protected override void OnPaint(PaintEventArgs e) 
    { 
     e.Graphics.DrawString(this.Text, this.Font, Brushes.Black, new PointF(0.0F, 0.0F)); 
    } 

    protected override void OnPaintBackground(PaintEventArgs e) 
    { 
     e.Graphics.DrawImage(BgBitmap, 0, 0); 
    } 
} 

...そしてここで私はインスタンス化する方法の関連する部分である:

Bitmap bgImage = (Bitmap)Bitmap.FromStream(Document.FormImage); 

PictureBox pb = new PictureBox(); 
pb.Image = bgImage; 
pb.Size = pb.Image.Size; 
pb.Top = 0; 
pb.Left = 0; 
panel1.Controls.Add(pb); 

foreach (FormField field in Document.FormFields) 
{ 
    TransparentTextbox tb = new TransparentTextbox(); 
    tb.Width = (int)Math.Ceiling(field.MaxLineWidth * 96.0); 
    tb.Height = 22; 
    tb.Font = new Font("Courier", 12); 
    tb.BorderStyle = BorderStyle.None; 
    tb.Text = "Super Neat!"; 
    tb.TextChanged += tb_TextChanged; 
    tb.Left = (int)Math.Ceiling(field.XValue * 96.0); 
    tb.Top = (int)Math.Ceiling(field.YValue * 96.0); 
    tb.Visible = true; 

    Bitmap b = new Bitmap(tb.Width, tb.Height); 
    using (Graphics g = Graphics.FromImage(b)) 
    { 
     g.DrawImage(bgImage, new Rectangle(0, 0, b.Width, b.Height), tb.Bounds, GraphicsUnit.Pixel); 
     tb.BgBitmap = b; 
    } 
    panel1.Controls.Add(tb); 
} 

私はまだテキストは、私はそれを強調表示したときに見て、そのような他のものが、私は正しい軌道に乗っていますように、私が感じる方法で作業する必要があります。他の実行可能な解説でコメントしてくれたReza AghaeiとMangistに+1してください!

関連する問題