[英]Invalidating all controls in a winform causes infinite calls of OnPaint method
我有两个扩展控件。 第一个称为LiveControl
,它继承自具有调整大小、旋转、移动...方法的PictureBox
。 第二个叫做DrawPanel
,它是从Panel
继承的,它是几个LiveControl
的父LiveControl
。
当一个LiveControl
移到另一个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
使所有LiveControl
都无效,它会导致对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
方法仍在不停地调用。 有谁知道如何解决这个问题?
Invalidate
触发Paint
。 在Paint
调用Invalidate
是一个无限循环。 不要那样做!
如果所有显示它的控件都DoubleBuffering
,则闪烁将消失。 请注意,要打开DoublBuffering
您可能需要对其中一些进行子类化,例如Panels
、 FlowLayoutPanels
或DGVs
.. 事实上,只有Form
公开它,并且默认情况下只有PictureBox
将其打开。
您还需要确保消除所有不必要的Invalidates
。 - 通常只有在绘图中需要的数据发生变化时才需要Invalidate
。 我在您的代码中根本看不到任何绘图。 否则,您有时可能需要调用Refresh
来消除撕裂,即“尾部”或“痕迹”。
我根本不会处理 OnPaint。 我想在 Paint 事件中自定义绘制。
在绘制更新的情况下,您永远不应该调用 Invalidate()。 如果您遇到闪烁问题,是否尝试在自定义控件和容器上将 DoubleBuffered 设置为 true?
如果您通过调用 DrawPanel.Invalidate() 使 DrawPanel 无效,则覆盖有一个名为bool invalidateChildren
的标志。 您是否尝试将其设置为 true?
希望这会有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.