为什么我的用户控件绘制事件不只在一个控件上填充我的矩形?
Why isn't my user control paint event filling my rectangle only on one control?
我不明白我做错了什么。
对于我创建的两个控件之一(第一个),它可以工作。但是对于第二个,不是吗?
我已经尝试了很多方法来解决这个问题,但我还没有更接近于任何想法的解决方案?
What happens
它们的创建代码:
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);
}
用户控件:
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() }");
}
}
您可以在构造函数中将 Usercontrol
的 BackColor
设置为 BubbleColor
。
BubbleColor = color;
现在看起来符合预期:
但是实际错误来自Bounds
属性。它是包含控件的矩形,它的位置是控件的位置,因此,根据数字,您主要绘制在气泡之外。
相反,您可以使用:
Rectangle rect = new Rectangle(Point.Empty, Bounds.Size);
但是最自然的解决方法是使用对属性,也就是ClientRectangle
..
而且,正如 Reza 的 cross-post 所说:请确保配置 GDI+ 资源,即画笔..
奇怪的行为是因为使用 Bounds
instead of ClientRectangle
。它们是不同的:
Bounds
:控件的大小和位置相对于父控件.
ClientRectangle
:代表控件客户区的矩形。
填充矩形时使用ClientRectangle
。
当您将尺寸为 (100, 100)
的控件放在父级的点 (10,10)
上时,客户端矩形将为 (0, 0, 100, 100)
,Bounds
将为 (10, 10, 100, 100)
.
注意:您需要处理GDI+对象,否则您很快就会面临GDI泄漏。在 using:
中创建和使用它们
using (var brush = new SolidBrush(this.BubbleColor))
e.Graphics.FillRectangle(brush, ClientRectangle);
我不明白我做错了什么。 对于我创建的两个控件之一(第一个),它可以工作。但是对于第二个,不是吗? 我已经尝试了很多方法来解决这个问题,但我还没有更接近于任何想法的解决方案?
What happens
它们的创建代码:
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);
}
用户控件:
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() }");
}
}
您可以在构造函数中将 Usercontrol
的 BackColor
设置为 BubbleColor
。
BubbleColor = color;
现在看起来符合预期:
但是实际错误来自Bounds
属性。它是包含控件的矩形,它的位置是控件的位置,因此,根据数字,您主要绘制在气泡之外。
相反,您可以使用:
Rectangle rect = new Rectangle(Point.Empty, Bounds.Size);
但是最自然的解决方法是使用对属性,也就是ClientRectangle
..
而且,正如 Reza 的 cross-post 所说:请确保配置 GDI+ 资源,即画笔..
奇怪的行为是因为使用 Bounds
instead of ClientRectangle
。它们是不同的:
Bounds
:控件的大小和位置相对于父控件.ClientRectangle
:代表控件客户区的矩形。
填充矩形时使用ClientRectangle
。
当您将尺寸为 (100, 100)
的控件放在父级的点 (10,10)
上时,客户端矩形将为 (0, 0, 100, 100)
,Bounds
将为 (10, 10, 100, 100)
.
注意:您需要处理GDI+对象,否则您很快就会面临GDI泄漏。在 using:
中创建和使用它们using (var brush = new SolidBrush(this.BubbleColor))
e.Graphics.FillRectangle(brush, ClientRectangle);