c# - Panel onPaint 渲染伪影
问题描述
我创建了面板类“GpanelBorder”,它使用代码在自定义面板中绘制边框:
namespace GetterControlsLibary
{
public class GpanelBorder : Panel
{
private Color colorBorder;
public GpanelBorder()
{
SetStyle(ControlStyles.UserPaint | ControlStyles.ResizeRedraw | ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.DrawRectangle(
new Pen(
new SolidBrush(colorBorder), 8),
e.ClipRectangle);
}
public Color BorderColor
{
get
{
return colorBorder;
}
set
{
colorBorder = value;
}
}
}
}
工作正常,但当我在设计模式下,鼠标点击面板内并移动鼠标或拖动此面板上的其他控件,工件被创建(下图)
如何解决?
解决方案
该.ClipRectangle
参数不一定代表要在其中绘制的控件的整个区域。它可能代表控件的较小部分,表明仅需要重新绘制该部分。在计算和重绘整个控件的成本太高的情况下,您可以使用“剪辑矩形”仅重绘控件的一部分。如果这种情况不适用于您,则使用ClientRectangle获取整个控件的边界并使用它来绘制边框。此外,您正在泄漏一支笔和一支 SOLIDBRUSH。当你用完这些资源时,你需要.Dispose()
这些资源。最好使用using
块来完成:
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
using (SolidBrush sb = new SolidBrush(colorBorder), 8))
{
using (Pen p = new Pen(sb))
{
e.Graphics.DrawRectangle(p, this.ClientRectangle);
}
}
}
您可能需要基于 ClientRectangle 创建一个新的 Rectangle 并在绘制之前根据自己的喜好对其进行调整。
推荐阅读
- checkbox - 如何在材料单元格内添加复选框并使用angular8检索组合记录
- c# - 如何在服务器端处理用户日期并根据用户时间而不是服务器每天发送通知
- html - 书写模式:在 Facebook 应用程序中打开网站时,vertical-rl 不起作用
- google-cloud-platform - 如何使存储桶 b1 的文件夹与谷歌云中的存储桶 b2 保持同步?
- google-bigquery - 使用 Bigquery 存储 API 时出错
- r - R:连续值函数之间的差值之和
- node.js - Nodejs socket.io 服务器选项
- flutter - 仅当 API 响应出现抖动时如何加载 UI?
- c++ - C++ 打印奇怪的行为(潜在的内存泄漏?)
- laravel - DataTable 标头在模态中不能很好地呈现