C # Winforms: Selectively disabling an interface when a thread starts

I have a rather complicated form that provides the ability to run a script (our own type). While it works, I do not want to completely block the user interface, so I would like to run it in the stream. So far so good, but so that the user does not bother with things, I need to selectively disable parts of the user interface. I could recursively set Enabled = false, and then Enabled = true when the thread ends. But this ignores the state of the control during operation (i.e., controls that were disabled for various reasons would be incorrectly enabled). If you don't build a boolean tree, is there another way to block input (for example, the GlassPane type in Java)?

+4
source share
3 answers

Do not use DoEvents , evil .

Use the panel and add all the controls you want to disable. When the panel is disabled, all internal controls will be disabled, but the value of their Enabled property will not actually be changed.

Here is a working example:

  public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { // Disables UI elements using the panel this.SetPanelEnabledProperty(false); // Starts the background work System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(this.Worker)); } private void Worker(object state) { // Simulates some work System.Threading.Thread.Sleep(2000); // Now the work is done, enable the panel this.SetPanelEnabledProperty(true); } private void SetPanelEnabledProperty(bool isEnabled) { // InvokeRequired is used to manage the case the UI is modified // from another thread that the UI thread if (this.panel1.InvokeRequired) { this.panel1.Invoke(new MethodInvoker(() => this.SetPanelEnabledProperty(isEnabled))); } else { this.panel1.Enabled = isEnabled; } } } 
+3
source

It is not possible to use a panel with controls that you want to disable when the script is running, and then turn on the panel again when the script ends.

Alternatively, you can run Process for the script.

+1
source

You can solve this either using the Application.DoEvents () method, or you need to write a delegate that invokes the control. I think Application.DoEvents () will be the easiest way. You must call Application.DoEvents () in your thread loop.

For the delegate version, you will find some information here: http://msdn.microsoft.com/de-de/library/zyzhdc6b.aspx

0
source

Source: https://habr.com/ru/post/1392932/


All Articles