问题
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