【发布时间】:2020-04-12 08:18:46
【问题描述】:
我有两个扩展控件。
第一个称为LiveControl,它继承自PictureBox,它具有调整大小、旋转、移动...方法。
第二个称为DrawPanel,它继承自Panel,它是多个LiveControls 的父代。
当一个LiveControl 移动到另一个时,我做了几件事来减少闪烁并留下痕迹。最后我用LiveControl中的以下代码实现了比我预期的更好:
MouseUp += (s, e) =>
{
foreach (Control c in Parent.Controls.OfType<LiveControl>())
c.Refresh();
};
MouseMove += (s, e) =>
{
if (e.Button == MouseButtons.Left)
{
Control x = (Control)s;
x.SuspendLayout();
x.Location = new Point(x.Left + e.X - cur.X, x.Top + e.Y - cur.Y);
x.ResumeLayout();
foreach (Control c in Parent.Controls.OfType<LiveControl>())
c.Update();
}
};
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
foreach (Control c in Parent.Controls.OfType<LiveControl>())
c.Invalidate();
}
但问题在于,正如上面的代码,每个LiveControl 的OnPaint 都会使所有LiveControls 无效,它会导致OnPaint 的无限调用,从而导致表单上的其他控件出现问题(他们工作很慢,有延迟)。
为了解决这个问题,我编辑了OnPaint 的代码,如下所示:
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (!((DrawPanel)Parent).Invalidating)
{
((DrawPanel)Parent).Invalidating = true;
((DrawPanel)Parent).InvalidatedCount = 0;
foreach (Control c in Parent.Controls.OfType<LiveControl>())
c.Invalidate();
}
else
{
((DrawPanel)Parent).InvalidatedCount++;
if (((DrawPanel)Parent).InvalidatedCount == ((DrawPanel)Parent).Controls.OfType<LiveControl>().Count())
{
((DrawPanel)Parent).InvalidatedCount = 0; ((DrawPanel)Parent).Invalidating = false;
}
}
}
但是OnPaint 方法仍然被不间断地调用。
有人知道如何解决这个问题吗?
【问题讨论】:
-
downvoter,你能说一下为什么吗?
-
尝试在 OnPaint 事件上分离绘画事件,并在完成任务后在控件上再次注册它。这可能会帮助您克服无限循环
-
@NiranjanKala 如果我分离 OnPaint 事件,
Invalidate()不会有任何好处。 -
由于
Invalidate导致Paint,从OnPaint调用Invalidate不是一个好主意。您真正想用该代码实现什么目标? -
不是我的反对意见,但有一个明显的无限循环表明缺乏研究。 - 在 Paint 中调用 Invalidate 是一个无限循环。期间。