Why isn't my user control paint event filling my rectangle only on one control?

我们两清 提交于 2019-12-24 16:12:10

问题


I can't understand what I'm doing wrong. For one of the two controls I create (the first one) it works. But for the second one, it doesn't? I've tried many things to fix this but I haven't come any closer to a solution any ideas?

What happens

Code where they are created:

    public MessageLogView()
    {
        MessageBubble bubble = new MessageBubble("Hey there Steve I love you", DateTime.Today, Color.FromArgb(255,255,255), new Padding(10, 10, 10, 10));

        bubble.Location = new Point(5, 5);

        this.Controls.Add(bubble);

        MessageBubble bubble2 = new MessageBubble("K, good for you", DateTime.Today, Color.FromArgb(220, 248, 198), new Padding(10, 10, 10, 10));

        bubble2.Location = new Point(5, 5 + bubble.BubbleHeight + 5);

        this.Controls.Add(bubble2);

    }

The usercontrol:

 public partial class MessageBubble : UserControl
{
    private string Text;
    private DateTime Date;
    private Color BubbleColor = Color.FromArgb(220, 248, 198);
    private Size stringSize, datestringSize;
    public Font textFont { get; set; } = new Font("Arial", 12, FontStyle.Regular);
    public Font dateFont { get; set; } = new Font("Arial", 9, FontStyle.Bold);
    public Color textColor { get; set; } = Color.Black;
    public Color dateColor { get; set; } = Color.FromArgb(180, 208, 158);
    public int cornerRadius { get; set; } = 5;

    public int BubbleHeight { get
        {
            return this.Padding.Top + this.Padding.Bottom + stringSize.Height + 5 + datestringSize.Height;
        }
    }
    public int BubbleWidth
    {
        get
        {
            return this.Padding.Left + this.Padding.Right + stringSize.Width;
        }
    }

    public MessageBubble(string text, DateTime date, Color color, Padding padding)
    {
        InitializeComponent();
        Text = text;
        this.BubbleColor = color;
        Date = date;
        stringSize = this.CreateGraphics().MeasureString(Text, this.textFont).ToSize();
        datestringSize = this.CreateGraphics().MeasureString(Date.ToString("hh:mm tt"), this.dateFont).ToSize();
        this.Padding = padding;
        this.Width = this.BubbleWidth;
        this.Height = this.BubbleHeight;
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        e.Graphics.FillRectangle(new SolidBrush(this.BubbleColor), Bounds);
        e.Graphics.DrawString(this.Text, this.textFont, new SolidBrush(this.textColor), new Point(this.Padding.Left,this.Padding.Top));
        e.Graphics.DrawString(this.Date.ToString("hh:mm tt"), this.dateFont, new SolidBrush(this.dateColor), new Point(this.Width - datestringSize.Width - Padding.Right, this.Padding.Top + stringSize.Height + 5));
        Console.WriteLine($"Drawn: {this.Text} - {this.Bounds.X}, {this.Bounds.Y} - {this.BubbleWidth}, {this.BubbleHeight}/{this.Bounds.Width}, {this.Bounds.Height} - {this.BubbleColor.ToString() }");
    }
}

回答1:


The strange behavior is because of using Bounds instead of ClientRectangle. They are different:

  • Bounds: Size and location of the control relative to the parent control.
  • ClientRectangle: The rectangle that represents the client area of the control.

Use ClientRectangle when filling rectangle.

When you put a control having (100, 100) as its size on the point (10,10) on the parent, client rectangle will be (0, 0, 100, 100) and Bounds will be (10, 10, 100, 100).

Note: You need to dispose the GDI+ objects, otherwise you will be faced with GDI leak soon. Create and use them in a using:

using (var brush = new SolidBrush(this.BubbleColor))
    e.Graphics.FillRectangle(brush, ClientRectangle);



回答2:


You can set the Usercontrol's BackColor to the BubbleColor in the constructor.

BubbleColor = color;

Now it looks as expected:

But the actual error comes from the Bounds property. It is the rectangle the control is contained in and its location is the controls's location, so, depending on the numbers, you are drawing mostly outside of the bubble.

Instead you could use:

Rectangle rect = new Rectangle(Point.Empty, Bounds.Size);

But the most natural solution is to use the right property, which is ClientRectangle..

And, as Reza's cross-post says: Do make sure to dispose you GDI+ resources, namely the Brushes..



来源:https://stackoverflow.com/questions/51001476/why-isnt-my-user-control-paint-event-filling-my-rectangle-only-on-one-control

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!