Why aren't UI components refreshed when updated from background thread?
I have a winform with some buttons that are updated in an event handler. The event is fired from a background thread, then the appearance is set via the Invoke method. The buttons will just get enabled or disabled. Something will happen at unpredicable times, though:
- The button will not change a开发者_如何学Cppearance visually. When it should be enabled, it still looks like it's disabled
- Clicking on the "disabled" button still fires the click event - as if its actually enabled underneath
- After resizing or moving the form, the component's appearance is set correctly to enabled.
- Only the components that are updated in this manner are affected. Other components on the form look/behave fine.
Here is how the button is getting updated in code:
public class Form1 :Form
{
void eventFromThread(object sender, CustomEventArgs e)
{
if(e.enable) RunOnUiThread(ShowEnabledView);
else RunOnUiThread(ShowDisabledView);
}
void ShowEnabledView()
{
button1.Enabled = true;
}
void ShowDisabledView()
{
button1.Enabled = false;
}
void RunOnUiThread(MethodInvoker method)
{
try
{
if(InvokeRequired)
{
Invoke(method);
}
else
method.Invoke();
}
catch(ObjectDisposedException)
{ return;}
catch(InvalidOperationException)
{return;}
}
}
I have tried forcing a refresh on the button, and it hasn't re-occurred yet, but its only been a couple of days. The issue just seems to pop up when it wants to, so I can't really be sure I'm fixing anything. Can anyone shed any light on this?
try calling
System.Windows.Forms.Application.DoEvents()
after you change the button's Enabled property
精彩评论