簡體   English   中英

Winforms標簽繪制在自定義繪圖的按鈕上

[英]Winforms label drawing over a button with custom drawing

所以我有這個小應用程序,有一個按鈕和一個標簽。 該按鈕具有自定義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); 將清除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 ,除非你需要對異常做一些事情,否則這會更加清晰。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM