【问题标题】:Winforms label drawing over a button with custom drawingWinforms 标签在带有自定义绘图的按钮上绘图
【发布时间】:2015-05-08 12:58:06
【问题描述】:

所以我有了这个有一个按钮和一个标签的小应用程序。该按钮有一个自定义的 OnPaint 方法,使其看起来独一无二。标签目前没有。然而,标签似乎无缘无故地在按钮内绘制。看看这个:

为了清楚起见,我已禁用渲染填充矩形,因为它主要涵盖了问题。这是我的按钮的 OnPaint 代码:

    protected override void OnPaint(PaintEventArgs e)
    {
        Graphics g = e.Graphics;
        g.SmoothingMode = SmoothingMode.HighQuality;
        Pen p = new Pen (Color.Black, 2);
        Rectangle fillRect = new Rectangle (e.ClipRectangle.X, e.ClipRectangle.Y, e.ClipRectangle.Width - 2, e.ClipRectangle.Height - 2);
        Brush b;
        if (MouseHovering)
        {
            b = new SolidBrush (Color.DarkSlateGray);
        } 
        else
        {
            b = new SolidBrush (Color.Gray);
        }
        //g.FillRectangle (b, fillRect);
        g.DrawRectangle (p, e.ClipRectangle);
        //g.DrawString (Text, new Font ("Arial", 8), new SolidBrush (Color.Black), new Point (4, 4));
    }

下面是在主窗体类中创建标签和按钮的代码:

label = new Label ();
label.Text = "Hello World";
label.Top = 15;
label.Left = 180;
label.AutoSize = true;
Controls.Add (label);
CButton b = new CButton ();
b.Text = "Click me for a new sentence";
b.AutoSize = true;
b.Top = 10; b.Left = 10;
Controls.Add (b);

上面是在构造函数中调用的。然后当按下按钮时,标签文本设置如下:

label.Text = Specifier + " " + Verb + " a " + CommonNoun;

那么这里发生了什么,我该如何解决?如果您需要任何其他代码来理解问题,请不要犹豫。

【问题讨论】:

  • 在您的绘画程序顶部尝试g.Clear(BackColor)。也不要使用剪裁矩形,只需使用Rectangle(0, 0, this.Width, this.Height);,并确保在结束时处理 GDI 对象(b.Dispose()p.Dispose()
  • 这解决了问题,谢谢!
  • @Ron Beyer 应该将此作为解决方案发布。所以可以接受。
  • @tgolisch 完成了,之前很忙,谢谢提醒。

标签: c# winforms


【解决方案1】:

有些东西不见了。 g.Clear(BackColor); 将清除 Graphics 对象正在绘制的缓冲区的内容。

protected override void OnPaint(PaintEventArgs e)
    {
        Graphics g = e.Graphics;
        g.Clear(BackColor);
        g.SmoothingMode = SmoothingMode.HighQuality;
        Pen p = new Pen (Color.Black, 2);
        Rectangle fillRect = new Rectangle (e.ClipRectangle.X, e.ClipRectangle.Y, e.ClipRectangle.Width - 2, e.ClipRectangle.Height - 2);
        Brush b;
        if (MouseHovering)
        {
            b = new SolidBrush (Color.DarkSlateGray);
        } 
        else
        {
            b = new SolidBrush (Color.Gray);
        }
        //g.FillRectangle (b, fillRect);
        g.DrawRectangle (p, e.ClipRectangle);
        //g.DrawString (Text, new Font ("Arial", 8), new SolidBrush (Color.Black), new Point (4, 4));
        b.Dispose();   //ADD THIS
        p.Dispose();   //ADD THIS TOO
    }

还请记住,处置您正在使用的任何 GDI 资源非常重要。这些可能是 .NET 结构,但它们确实是后台的非托管对象。正确处理它们将防止内存泄漏和难以理解的崩溃。

另外,您不应该使用剪辑矩形,而是使用控件的实际边界。

最好的选择是将它们包装在 using 语句中:

protected override void OnPaint(PaintEventArgs e)
    {
        Graphics g = e.Graphics;
        g.SmoothingMode = SmoothingMode.HighQuality;

        Color fillColor = MouseHovering ? Color.DarkSlateGray : Color.Gray;

        using (Pen p = new Pen(Color.Black, 2))
        using (Brush b = new SolidBrush(fillColor))
        {
            Rectangle fillRect = new Rectangle (0, 0, this.Width, this.Height);

            g.DrawRectangle (p, e.ClipRectangle);
        }
    }

使用using 语句的额外好处是,如果在使用中出现异常,对象仍将被正确处理。另一种选择是将它们包装在try..catch..finally 中,但除非您需要对异常进行处理,否则这样会更干净。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-02
    • 1970-01-01
    • 2011-09-12
    • 1970-01-01
    • 1970-01-01
    • 2021-02-15
    相关资源
    最近更新 更多