29

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

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

我想要的是将标签放在进度条顶部,以便其文本在进度条“中”...

4

11 回答 11

32

向您的项目添加一个新类并发布如下所示的代码。建造。将新控件从工具箱顶部拖放到表单上。

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;
    }
  }
}
于 2009-03-03T21:22:16.030 回答
14

WinForms 并不真正支持透明控件,但是你可以自己制作一个透明控件。在这里查看我的答案

在您的情况下,您可能应该子类化进度条并覆盖 OnPaint 方法以在进度条上绘制文本。

于 2009-03-03T10:57:22.023 回答
7

最简单的解决方案如下:

  1. 在可视化编辑器或表单的构造函数中将背景颜色设置为透明度:

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

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

    this.label1.Parent = progressBar1;

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

于 2011-08-09T07:33:12.960 回答
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;
    }
于 2011-03-25T21:50:48.777 回答
2

这是一个非常简单的解决方案,效果很好:

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

于 2014-02-12T10:54:56.260 回答
1

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

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

<TextBox Width="200" Height="40" Opacity="0.5"/>
于 2009-03-03T11:13:29.003 回答
1

这是我不久前写的一个透明控件,它显示旋转的文本。大部分代码都来自这里,尽管 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);
        }
    }
}
于 2010-05-26T14:54:54.763 回答
0

因此,正如对我之前回答的评论所述,控制是默认行为,并且我记得是透明的。

无论如何,您是否尝试过设置 UserControl 的背景属性或标签所在的容器(面板、表单等?),您的标签应该反映该颜色 :)


旧答案:我已经有一段时间没有进行 winforms 编程了,但我记得标签默认是透明的?因此,它只有获得实际颜色的文本,而免费的颜色模仿它背后的任何东西:)

于 2009-03-03T10:50:58.340 回答
0

完全可以做到你想要达到的目标。玩控件只需要一点时间。可以创建一个具有透明背景的 Label 控件,并将其放在 Progressbar 控件的顶部。

检查我对另一个 SO 问题的回答。

于 2009-10-05T17:30:11.570 回答
0

至于对您的问题的解释,Windows 不会像您期望的那样对背景控件进行透明度 - 我猜灰色背景实际上是表单的表面。在表单表面和标签之间绘制的任何控件都将被忽略。

于 2009-10-05T17:42:00.207 回答
-3

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

        this.label1.BackColor = System.Drawing.Color.Transparent;
于 2010-02-13T03:01:16.510 回答