2009-03-03 65 views
27

为什么我不能将标签的背景色设置为透明?我以前做过,但现在它只是不想...为什么WinForms标签不想透明的原因?

我创建了一个新的UserControl,添加了一个进度条和一个标签。当我将标签的BackColor设置为透明时,它仍然是灰色= /为什么这是?

我想什么是对进度的顶部的标签,以便“在”进度条,它的文本是......

+0

查看alexander willemse的回答。 – blez 2012-09-21 15:18:28

+0

关于最后一句话(将文本放入进度栏):[Microsoft的进度条指导](http://msdn.microsoft.com/en-us/library/windows/desktop/aa511486.aspx)说:_Don'将完成百分比或任何其他文本放在进度条上。这样的文本是不可访问的,并且与使用主题不兼容。因此,如果您可以找到另一种方式,它将更加兼容,并且看起来更好,更一致。请参阅上面链接的指导。 – miroxlav 2013-12-07 23:10:44

回答

14

WinForms并不真正支持透明控件,但您可以自己制作透明控件。 See my answer here

在你的情况下,你应该继承进度条的子类并覆盖OnPaint方法在进度条上绘制文本。

+0

如何绘制进度条上的文本? – Svish 2009-03-03 14:06:40

+0

我还没有为进度条做过这件事,但是可以为OnPaint方法创建一个重载。在这里,您首先调用base.OnPaint,然后使用事件参数中传递的图形对象在控件上绘制文本。 – 2009-03-03 14:30:45

+4

不知道为什么在此页面的另一个答案中给出了完整的解决方案时,为什么回答指向另一个SO答案,即“在Google上查询”而不是提供方法的重要细节的答案。 – jwg 2013-01-15 10:43:20

0

从而为我以前的答案的评论指出,控制是默认行为,我记得它是透明的。

反正,你有没有尝试设置你的用户控件的背景属性,或者你的标签是在(小组形式,无论?)的容器,你的标签应反映颜色:)


老回答: 自从我做了winforms编程以来,它已经有一段时间了,但是我记得标签在默认情况下是透明的吗?因此它只有获得实际颜色的文本和无色模仿其背后的任何内容:)

+0

不,标签默认情况下有一个控制背景。但是,您将它设置为透明是正确的,它模仿了托管它的控件的颜色,因此它将背景描绘为纯灰色。 – 2009-03-03 11:00:20

+0

应该启动WinForms并检查:P,true Control是默认行为,它看起来似乎是透明的,因为它们共享相同的颜色:) – thmsn 2009-03-03 11:34:13

1

如果你想专注于设计你的Windows应用程序,我建议你使用WPF。

使控件在WPF中透明是很容易的。

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

我确信WPF能够正确地完成透明标签,但是只是想指出,如果将此示例中的代码应用于Label,它将使文本变为半透明 - 这不是我们所期望的! – 2009-11-06 23:26:59

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 2009-03-05 13:53:23

0

这是可以做到你想要达到的。只需要一点时间来玩控制。可以使用透明背景创建Label控件,并将其放置在Progressbar控件的顶部。

检查my answer to另一个SO问题。

0

至于你的问题的解释,Windows不会像你所期望的那样为背景控制执行透明度 - 我猜测灰色背景实际上是表单的表面。无论是在表单表面和标签之间绘制的控件都被忽略。

-3

选择BackColor,转到Web选项卡,然后选择透明。生成以下内容。

 this.label1.BackColor = System.Drawing.Color.Transparent; 
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; 
    } 
6

最简单的解决方案如下:

  1. 设置背景颜色透明度无论是在可视化编辑器或在窗体的构造函数:

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

  2. 设置您的标签的父属性,以控制您希望在文本后面可见的标签。这可以在窗体构造函数或Load方法中完成:

    this.label1.Parent = progressBar1;

它的确如此,在DirectX中这不是真正的透明度。您在显示中看到的结果仅由两层组成。你不能用这种方法总结两层以上(每层都有自己的透明度由alpha参数定义)。但它适用于Winforms编程中可能遇到的许多实际情况。

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,但我们也必须触发绘画事件。