2009-03-03 11 views
27

ラベルのBackColorを透明に設定できないのはなぜですか?私は前にそれをやったことがありますが、今はただしたくない...なぜWinFormsラベルが透明になりたくないのか?

新しいUserControlを作成し、プログレスバーとラベルを追加しました。ラベルのBackColorを透明に設定すると、まだグレー= /これはなぜですか?私が望んで

は、そのように述べられ、私の前の回答にコメントとして、コントロールがデフォルトの動作です...そのテキストはプログレスバー「に」だったように、プログレスバーの上にラベルを持つように

+0

alexander willemseの答えを参照してください。 – blez

+0

最後の文章について(プログレスバーにテキストを入力する):[Microsoftのプログレスバーガイドライン](http://msdn.microsoft.com/en-us/library/windows/desktop/aa511486.aspx)と言っている:_Don '完了率またはその他のテキストを進行状況バーに入力します。このようなテキストにはアクセスできず、テーマの使用にも対応していません。他の方法を見つけることができれば、より互換性があり、よりよく見えるようになります。上記のガイドラインをご覧ください。 – miroxlav

答えて

14

WinFormsは実際に透過的なコントロールをサポートしていません。 See my answer here

場合によっては、プログレスバーをサブクラス化して、OnPaintメソッドをオーバーライドして、プログレスバーにテキストを描画する必要があります。

+0

どのようにプログレスバーにテキストを描画しますか? – Svish

+0

これはプログレスバーでは行っていませんが、OnPaintメソッドのオーバーロードを作成できます。ここでは、最初にbase.OnPaintを呼び出してから、イベント引数で渡されたグラフィックスオブジェクトを使用して、コントロールの上にテキストを描画します。 –

+4

このページの別の回答で完全な解決策が提示された場合、他のSO回答を参照する回答が、理由を明らかにするよりも「Googleで検索する」と言われる理由は不明です。 – jwg

0

ました私は透明であると覚えています。

はとにかく、あなたのユーザーコントロールの背景プロパティを設定しようとしている、またはコンテナあなたのラベルが入っている(パネル、フォーム、何?)、あなたのラベルは、その色を反映すべきである:)


旧回答: 私はwinformsのプログラミングをして以来、しばらくしていますが、ラベルはデフォルトごとに透過的です。したがって、実際の色を取得するテキストと背景色は、背後にあるものを模倣します。

+0

いいえ、デフォルトでLabelにはControl of Backgroundがあります。しかし、透明に設定すると、それをホストしているコントロールの色を模倣しているので、背景を実線の灰色で塗りつぶします。 –

+0

WinFormsを起動してチェックする必要があります:P trueコントロールはデフォルトの動作です。同じ色を共有しているので透明に見えます:) – thmsn

1

Windowsアプリケーションの設計に専念する場合は、WPFを使用することをお勧めします。

コントロールをWPFで透明にすることは非常に簡単です。

<TextBox Width="200" Height="40" Opacity="0.5"/> 
+6

私はWPFが透明なラベルを正しく行っていると確信していますが、この例のコードをLabelに適用すると、テキストも半透明になります。 –

29

新しいクラスをプロジェクトに追加し、下のコードを送信してください。ビルド。新しいコントロールをツールボックスの上部からフォームにドロップします。

using System; 
using System.Windows.Forms; 

public class TransparentLabel : Label { 
    public TransparentLabel() { 
    this.SetStyle(ControlStyles.Opaque, true); 
    this.SetStyle(ControlStyles.OptimizedDoubleBuffer, false); 
    } 
    protected override CreateParams CreateParams { 
    get { 
     CreateParams parms = base.CreateParams; 
     parms.ExStyle |= 0x20; // Turn on WS_EX_TRANSPARENT 
     return parms; 
    } 
    } 
} 
+0

これはほとんど動作するようです。問題は、プログレスバーの上にあるときです。テキストが消えて時々再現されるようです... – Svish

+0

プログレスバーの値を何かに設定するとテキストが消えます。 – Svish

+0

スタッキングエフェクトはサポートされていません。 –

0

達成したいことを正確に行うことは可能です。コントロールで遊ぶのに少し時間がかかります。透明な背景を持つLabelコントロールを作成し、Progressbarコントロールの上に配置することは可能です。

チェックmy answer toもう1つの質問です。

0

あなたの問題の説明として、ウィンドウは、灰色の背景が実際にフォームのサーフェスであると推測しているような、バックグラウンドコントロールの透明度を行いません。フォームのサーフェスとラベルの間に描画されるコントロールは無視されます。

-3

BackColorを選択し、[Web]タブに移動し、[透過]を選択します。以下を生成します。

 this.label1.BackColor = System.Drawing.Color.Transparent; 
+0

これは私がやったことですが、プログレスバーの上にあるときはうまくいきません:) – Svish

1

ここは、回転したテキストを表示しています。コードのほとんどはhereから来ますが、IIRCは動作させるためにいくつかの調整が必要でしたが、

using System; 
using System.Drawing; 
using System.Drawing.Drawing2D; 
using System.Drawing.Text; 
using System.Linq; 
using System.Windows.Forms; 

namespace MyNamespace 
{ 
    public partial class RotatedText : UserControl 
    { 
     private readonly Timer _invalidationTimer; 
     private const int WS_EX_TRANSPARENT = 0x00000020; 

     public RotatedText() 
     { 
      this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); 
      InitializeComponent(); 

      _invalidationTimer = new Timer {Interval = 500, Enabled = true}; 
      _invalidationTimer.Tick += TickHandler; 
     } 

     [Browsable(true)] 
     [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] 
     [Category("Appearance")] 
     [Description("Text which appears in control")] 
     public string Text { get; set; } 

     #region Transparent background 
     protected override CreateParams CreateParams 
     { 
      get 
      { 
       CreateParams cp = base.CreateParams; 
       cp.ExStyle |= WS_EX_TRANSPARENT; 
       return cp; 
      } 
     } 

     private void TickHandler(object sender, EventArgs e) 
     { 
      InvalidateEx(); 
     } 

     private void InvalidateEx() 
     { 
      if (Parent != null) 
       Parent.Invalidate(Bounds, false); 
      else 
       Invalidate(); 
     } 

     protected override void OnPaintBackground(PaintEventArgs e) 
     { 
      //Intentionally do nothing - stops background from drawing 
      //base.OnPaintBackground(e); 
     } 
     #endregion 

     //Rotate text and draw 
     protected override void OnPaint(PaintEventArgs e) 
     { 
      double angleRadians = Math.Atan2(Height, Width); 
      float angleDegrees = -1*(float) (angleRadians*180/Math.PI); 
      angleDegrees *= 0.9f; 
      e.Graphics.RotateTransform(angleDegrees, MatrixOrder.Append); 
      e.Graphics.TranslateTransform(20, Height - 75, MatrixOrder.Append); 
      e.Graphics.TextRenderingHint = TextRenderingHint.AntiAliasGridFit; 
      Font font = new Font("Ariel", 50); 
      e.Graphics.DrawString(Text, font, Brushes.Gray, 1, 2); //Shadow 
      e.Graphics.DrawString(Text, font, Brushes.Red, 0, 0); 
     } 
    } 
} 
4

にLinkLabelない通常のラベル

private void MakeTransparentLabel(System.Windows.Forms.LinkLabel LinkLabel) 
    { 
     this.MakeTransparentLabel(LinkLabel, Color.White); 
    } 
    private void MakeTransparentLabel(System.Windows.Forms.LinkLabel LinkLabel, Color ForeColor) 
    { 
     LinkLabel.ForeColor = ForeColor; 
     LinkLabel.LinkColor = ForeColor; 
     LinkLabel.VisitedLinkColor = ForeColor; 
     LinkLabel.ActiveLinkColor = ForeColor; 
     LinkLabel.DisabledLinkColor = ForeColor; 
     LinkLabel.LinkArea = new LinkArea(0, 0); 
     LinkLabel.LinkBehavior = LinkBehavior.NeverUnderline; 
     LinkLabel.Cursor = Cursors.Arrow; 
     LinkLabel.BackColor = Color.Transparent; 
    } 
    private void SetTransparentLabelText(System.Windows.Forms.LinkLabel LinkLabel, string Text) 
    { 
     if (string.IsNullOrEmpty(Text)) { LinkLabel.Text = " "; return; } 
     LinkLabel.Text = Text; 
    } 
+0

ありがとうございました。それは私に多くの仕事を助けました。 – blez

6

ほとんどのシンプルなソリューションを使用して、以下の通りです:

  1. 設定の背景色は、ビジュアルエディタまたはフォームのコンストラクタのいずれかで透明性のために:

    this.label1.BackColor = System.Drawing.Color.Transparent;

  2. ラベルのParentプロパティを設定して、テキストの背後に表示するように設定します。これは、フォームコンストラクタまたはLoadメソッドで行うことができます。

    this.label1.Parent = progressBar1;

これは、DirectXのように真の透明性ではないということは事実です。表示される結果は、2つのレイヤーからのみ構成されます。このアプローチでは、2つ以上のレイヤーを合計できません(各レイヤーは、アルファパラメーターで定義された独自の透明度を持ちます)。しかし、WinFormsのプログラミングで遭遇する多くの実用的な状況に適しています。

+0

素敵なトリック - ラベルにラベルが必要でした。 –

1

これは非常にシンプルなソリューションであり、素晴らしい作品:ラベルの背景色が透明である場合にはそのラベルの背景色が一定になった後

public class MyLabel : Label 
{ 
    private bool fTransparent = false; 
    public bool Transparent 
    { 
     get { return fTransparent; } 
     set { fTransparent = value; } 
    } 
    public MyLabel() : base() 
    { 
    } 
    protected override CreateParams CreateParams 
    { 
     get 
     { 
      if (fTransparent) 
      { 
       CreateParams cp = base.CreateParams; 
       cp.ExStyle |= 0x00000020; //WS_EX_TRANSPARENT 
       return cp; 
      } 
      else return base.CreateParams; 
     } 
    } 
    protected override void WndProc(ref Message m) 
    { 
     if (fTransparent) 
     { 
      if (m.Msg != 0x14 /*WM_ERASEBKGND*/ && m.Msg != 0x0F /*WM_PAINT*/) 
       base.WndProc(ref m); 
      else 
      { 
       if (m.Msg == 0x0F) // WM_PAINT 
        base.OnPaint(new PaintEventArgs(Graphics.FromHwnd(Handle), ClientRectangle)); 
       DefWndProc(ref m); 
      } 
     } 
     else base.WndProc(ref m); 
    } 
} 

は、その後、ラベルは、それが作成されて初めてその基礎となる制御を撮影します。そしてラベルがそれ自身を再描画するたびに、その固定された色やパターンに再描画されます。

CreateParamsを無効にすると、コントロールのウィンドウをどのように作成するかに影響します。これにより、実際の透過性が実現します。

WndProcをオーバーライドすると、どのメッセージを基本クラスに渡すかを制御します。 WM_ERASEBKGNDとWM_PAINTをフィルタ処理する必要がありますが、ペイントイベントをトリガする必要もあります。

+0

動きのあるプログレスバーの上で動作しますか? – Svish

+0

これは、ネイティブのアンダーレイコントロールにペイントしないように指示する方法なので、うまくいくはずです。 –

関連する問題