【问题标题】:Transparent controls on painted form绘制表单上的透明控件
【发布时间】:2011-09-11 19:34:12
【问题描述】:

使用 C# WinForms 我有一个表单,我在其上绘制从浅蓝色到深蓝色的渐变背景。我上面有一些按钮和几个标签似乎有效。

但我注意到,即使代码仅在 form_paint 事件上,绘画也会给标签上色。

如何使标签不包含相同的等级阴影,但要透明?例如表单顶部的标签为浅蓝色,而底部的标签为深蓝色。

private void frmOptions_Paint(object sender, PaintEventArgs e)
{
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
    Rectangle rectangle = e.ClipRectangle;

    using (Brush aBrush = new LinearGradientBrush(rectangle, Color.LightBlue, Color.DarkBlue, LinearGradientMode.Vertical))
    {
        e.Graphics.FillRectangle(aBrush, rectangle);
    }
}

非常感谢您对此提供的任何帮助。

编辑: 我刚刚通过代码行来调试它,并注意到正在为表单上的每个对象调用绘制事件 - 标签和按钮,上面第 2 行的矩形具有每次的大小。所以我现在真的很困惑为什么要为表单上的每个对象调用它。

编辑 2: 刚刚浏览了我的快速测试项目的代码(见下面的评论),还注意到每个对象都调用了绘制事件。不同之处在于测试项目没有“Rectangle rectangle = e.ClipRectangle;”行 - 它基本上使用表单的宽度和高度。我上面的代码将矩形设置为 ClipRectangle - 这是每个标签和按钮的大小......这是正常行为吗?如果是这样,那么看起来我需要遵循 Reniuz 下面的答案。

编辑 3 我已将 cliprectangle 线更改为“Rectangle rectangle = new Rectangle(0, 0, this.Width, this.Height);”这似乎使透明看起来应该如何,但是仍然为表单上的每个对象调用绘制事件 - 干得好,只有 7 个,所以它是绘制 8 次 :( 认为我仍然会查看“TransparentLabel”代码来测试它。

【问题讨论】:

  • 您是否尝试将这些标签的 BackColor 属性设置为透明?默认情况下,子控件继承其父容器的视觉属性...
  • 是的,标签和命令按钮的背景色属性设置为透明。
  • 嗯。然后检查以确保只有表单注册了 frmOptions_Paint 处理程序。您的症状听起来像是标签可能附有此处理程序,以及导致发生相同类型的绘画。
  • 不,只有表单有绘画处理程序 - 我只是添加了几个标签和命令按钮,将标签背景色设置为透明,并注意到绘画也在标签上,更改了按钮背景色并再次对其进行分级。看起来很奇怪,不是我所期望的行为。
  • @Paul Sasik - 嗯,刚刚创建了一个新的 winform 项目,在绘画事件中应用了分级背景,然后添加了一些标签和按钮,设置透明背景 - 正如预期的那样,一切都很好! - 我检查了该表单是否与我自己的表单具有相同的设置,并且它仍然可以正常工作,因此我自己的应用程序表单有问题。 :(

标签: c# winforms gdi


【解决方案1】:

看看this的文章。

编辑:

你也可以使用这个代码:

public class TransparentLabel : Control
{
    public TransparentLabel(Label label)
    {
        //setting default properties
        this.Text = label.Text;
        this.Font = label.Font;
        this.Location = label.Location;
        this.Size = label.Size;
        this.Parent = label.Parent;
        this.BringToFront();
        label.Dispose();

        TabStop = false;
    }

    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.ExStyle |= 0x20;
            return cp;
        }
    }

    protected override void OnPaintBackground(PaintEventArgs e)
    {
        // do nothing
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        DrawText();
    }

    protected override void WndProc(ref Message m)
    {
        base.WndProc(ref m);
        if(m.Msg == 0x000F)
        {
            DrawText();
        }
    }

    private void DrawText()
    {
        using(Graphics graphics = CreateGraphics())
        using(SolidBrush brush = new SolidBrush(ForeColor))
        {
            SizeF size = graphics.MeasureString(Text, Font);

            // first figure out the top
            float top = 0;
            switch(textAlign)
            {
                case ContentAlignment.MiddleLeft:
                case ContentAlignment.MiddleCenter:
                case ContentAlignment.MiddleRight:
                    top = (Height - size.Height) / 2;
                    break;
                case ContentAlignment.BottomLeft:
                case ContentAlignment.BottomCenter:
                case ContentAlignment.BottomRight:
                    top = Height - size.Height;
                    break;
            }

            float left = -1;
            switch(textAlign)
            {
                case ContentAlignment.TopLeft:
                case ContentAlignment.MiddleLeft:
                case ContentAlignment.BottomLeft:
                    if(RightToLeft == RightToLeft.Yes)
                        left = Width - size.Width;
                    else
                        left = -1;
                    break;
                case ContentAlignment.TopCenter:
                case ContentAlignment.MiddleCenter:
                case ContentAlignment.BottomCenter:
                    left = (Width - size.Width) / 2;
                    break;
                case ContentAlignment.TopRight:
                case ContentAlignment.MiddleRight:
                case ContentAlignment.BottomRight:
                    if(RightToLeft == RightToLeft.Yes)
                        left = -1;
                    else
                        left = Width - size.Width;
                    break;
            }
            graphics.DrawString(Text, Font, brush, left, top);
        }
    }

    public override string Text
    {
        get
        {
            return base.Text;
        }
        set
        {
            base.Text = value;
            RecreateHandle();
        }
    }

    public override RightToLeft RightToLeft
    {
        get
        {
            return base.RightToLeft;
        }
        set
        {
            base.RightToLeft = value;
            RecreateHandle();
        }
    }

    public override Font Font
    {
        get
        {
            return base.Font;
        }
        set
        {
            base.Font = value;
            RecreateHandle();
        }
    }

    private ContentAlignment textAlign = ContentAlignment.TopLeft;
    public ContentAlignment TextAlign
    {
        get { return textAlign; }
        set
        {
            textAlign = value;
            RecreateHandle();
        }
    }
}

透明标签将替换您现有的标签,因此您可以像这样使用它:

TransparentLabel transparentLabel1 = new TransparentLabel(label1);
TransparentLabel transparentLabel2 = new TransparentLabel(label2);

然后你应该会看到结果(左边是设计时间,右边是运行时间):

【讨论】:

  • 感谢您提供详细的帖子和文章的链接。我明天上班的时候看看这个。
猜你喜欢
  • 2013-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-15
  • 1970-01-01
  • 1970-01-01
  • 2016-06-10
  • 2011-12-14
相关资源
最近更新 更多