使winform中的所有控件无效会导致无限次调用OnPaint方法

时间:2016-10-12 05:23:50

标签: c# winforms

我有两个Extented控件。 第一个叫做LiveControl,它继承自PictureBox,它有Resizing,Rotation,Move,......方法。 第二个称为DrawPanel,它继承自Panel,它是几个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

//connect to mysql database $connection = mysqli_connect($hostname, $username, $password, $database) or die("Error " . mysqli_error($connection)); // open the csv file $fp = fopen($filename,"r"); //parse the csv file row by row while(($row = fgetcsv($fp,"500",",")) != FALSE) { //insert csv data into mysql table $sql = "INSERT INTO table92108 (date,filename,directory,type,email) VALUES('" . implode("','",$row) . "')"; if(!mysqli_query($connection, $sql)) { die('Error : ' . mysqli_error()); } } fclose($fp); //close the db connection mysqli_close($connection); ?> 方法仍被称为不间断。 有没有人知道如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

我根本不会处理OnPaint。我想在Paint事件中进行自定义绘制。

在绘画更新情况下,绝不应该调用Invalidate()。 如果您遇到闪烁问题,您是否尝试在自定义控件和容器上将DoubleBuffered设置为true?

如果通过调用DrawPanel.Invalidate()使DrawPanel无效,则一个覆盖有一个名为bool invalidateChildren的标志。您是否尝试将其设置为true?

希望这会有所帮助。

答案 1 :(得分:1)

Invalidate触发Paint。在Invalidate中调用Paint是一个无限循环。不要那样做!

如果所有控件显示其上有DoubleBuffering,则闪烁将消失。 注意要启用DoublBuffering,您可能需要继承其中一些内容,例如PanelsFlowLayoutPanels或{{1}实际上只有DGVs公开了它,并且只有Form默认启用它。

您还需要确保消除所有不必要的 PictureBox。 - 通常只有在图纸数据 数据 更改时才需要Invalidates。我根本没有在您的代码中看到任何绘图。否则,您有时可能需要致电Invalidate以消除撕裂,即“尾巴”或“痕迹”。