我有一个绘画事件,看起来像这样:
private void panel1_Paint(object sender, PaintEventArgs e)
{
Rectangle rec = new Rectangle(2, 2, 820, 620);
Pen pi = new Pen(Color.Black, 2);
e.Graphics.DrawRectangle(pi, rec);
Rectangle rec2 = new Rectangle(Convert.ToInt32((410 + 2500 * GlobaleVariablen.IstWerte[0])), Convert.ToInt32(310 + 1875 * GlobaleVariablen.IstWerte[1]), 2, 2);
e.Graphics.DrawRectangle(pi,rec2);
}
我有一个来自串行端口的数据流,每次接收数据时,我都想使rec2无效,而不是使整个表格无效。我能够通过以下方式在Datareceived事件中使整个表单无效:
panel1.Invalidate();
但是我不知道如何才能使我的rec2无效,因为如果您始终使用数据流使整个表单无效,那么它会像疯了似的闪烁,而且看起来确实不是很好。
Invalidate()
具有Rectangle
您要使其无效的重载版本:
panel1.Invalidate(GetRect2());
其中GetRect2()
(请选择一个更好的名称)是这样的:
static Rectangle GetRect2() {
int x Convert.ToInt32((410 + 2500 * GlobaleVariablen.IstWerte[0]));
int y = Convert.ToInt32(310 + 1875 * GlobaleVariablen.IstWerte[1]);
return new Rectangle(x, y, 2, 2);
}
在绘画事件处理程序中,您首先需要检查无效区域是否与您要编写的每个对象相交(示例很简单,因为您使用的是矩形,并且填充速度并不慢)。
在代码中进一步损害性能的是,实际上您正在Pen
为每个绘制操作创建一个新代码。您必须绝对避免这种情况:必须重用扩展的本机资源。最终代码可能类似于:
private Pen _pen = new Pen(Color.Black, 2);
private void panel1_Paint(object sender, PaintEventArgs e)
{
var rec = new Rectangle(2, 2, 820, 620);
if (e.ClipRectangle.IntersectsWith(rec))
e.Graphics.DrawRectangle(_pen, rec);
var rec2 = GetRect2();
if (e.ClipRectangle.IntersectsWith(rec2))
e.Graphics.DrawRectangle(pi, rec2);
}
现在,您的代码已稍作优化,但仍可能会闪烁。为避免这种情况,您必须为面板启用双重缓冲。从您自己的类派生Panel
并添加其构造函数:
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
重构代码并在单独的类中移动某些绘制逻辑(但不是面板本身)也是一个很好的机会。请参考MSDN以获得您可能需要使用的其他标志(例如AllPaintingInWmPaint
)。
最后说明:您对坐标进行了硬编码,除非您有固定大小的面板(带有或不带有滚动),否则这不是一个好习惯,因为它无法随着将来的更改很好地缩放,并且在许多情况下(一旦您将代码将比虚构示例稍微复杂一些)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句