如何防止UI逐个重绘每个控件

本文关键字:控件 UI 何防止 | 更新日期: 2023-09-27 18:09:28

在我的用户控件中执行一个冗长的操作。为了防止用户点击UI,我显示了一个进度条,并禁用了整个UI,如下所示:

this.Enabled = false;
ShowProgressBar();
DoLengthyOperation();
RemoveProgressBar();
this.Enabled = true;

这个工作正常。然而,我的用户控件上有许多其他控件,这些控件内部也有控件,这些控件内部也有控件,……等。

this.Enabled = false 
因此,

调用禁用了许多控件。这是有意为之。但我的问题是,你可以看到UI一个接一个地禁用每个控件。它运行得非常快,但是因为有很多控件,你实际上可以看到它在所有控件中运行。这看起来不专业,它使屏幕闪烁,我的眼睛疼。

是否有一种方法,使我可以防止UI重绘,直到所有控件被禁用,然后执行单个重绘?

我希望这不是一个愚蠢的问题;)

不知道这是否相关:我的控件派生自DevExpress.XtraEditors.XtraUserControl.

如何防止UI逐个重绘每个控件

您试过这个表单了吗?SuspendLayout和form . resumayout ?这似乎是你需要的。在msdn网站上有更多的信息。

在你想重新绘制之前调用suspendlayout,然后在禁用所有控件后继续。

this.SuspendLayout();
ShowProgressBar();
DoLengthyOperation();
RemoveProgressBar();
this.ResumeLayout();

如果进度条在表单上,您必须在暂停布局之前"显示"它。对不起,我没听清。

try this:

this.Invalidate();  // Invalidate the whole window
this.Enabled = false;
this.Refresh(); // Redraw every invalidated part of the window, so everything

建议的解决方案似乎都不起作用。

我认为问题的一部分是我使用DevExpress和每个控件不直接包含它的子控件,但使用LayoutControlGroups和LayoutControls和面板等。因此,实际使用的控件数量比您在屏幕上看到的需要禁用的实际控件数量要高得多。

所以我只是添加了我自己的递归函数,它只禁用某些类型的控件,在我的例子中是按钮和编辑框。其余的都被忽略了。这不仅更快,而且看起来也更好。再也不闪烁了。

我想我会使用这个解决方案,但是我非常感谢每个人在这里给出答案或评论的努力,谢谢!

现在我发现我的问题似乎是这个问题的副本:我如何暂停一个控件及其子控件的绘画?

您可以尝试在控件中添加双重缓冲。这不会阻止画的。然而,它应该有助于你的问题的视觉部分。

System.Reflection.PropertyInfo aProp =
        typeof(System.Windows.Forms.Control).GetProperty("DoubleBuffered",
        System.Reflection.BindingFlags.NonPublic |
        System.Reflection.BindingFlags.Instance);
 aProp.SetValue(YourControlNameHere, true, null);

注意:默认情况下,大多数控件已经将此设置为true。您的usercontrol可能没有,所以您可以测试一下这是否有帮助。

您可以将控件放入容器(称为groupControls),将容器的可见属性设置为false,(有一个启动屏幕出现或同等大小的容器"更新"或任何变得可见-叫它groupUpdateSplash)更新控件关闭飞溅容器可见并打开控制容器可见

groupControls.visible = false
groupUpdateSplash.visible = true
/* update controls and everything */
groupUpdateSplash.visible = false
groupControls.visible = true