gpt4 book ai didi

c# - 如何从另一个事件/类调用 ​​Invalidate not for the whole panel

转载 作者:太空宇宙 更新时间:2023-11-03 10:32:24 28 4
gpt4 key购买 nike

我有一个看起来像这样的绘画事件:

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)。

最后注意:你硬编码坐标,这不是一个好的做法,除非你有一个固定大小的面板(有或没有滚动),因为它不会随着 future 的变化很好地缩放,并且在许多情况下它可能会被破坏(如很快你的代码就会变得比虚构的例子稍微复杂一点)。

关于c# - 如何从另一个事件/类调用 ​​Invalidate not for the whole panel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29513155/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com