Why does my busy indicator work when I click but not for the default button?
Hard question to describe in one line so here's the detail.
I asked a question before about showing a busy indicator in a WPF window whilst doing some long-running action. The original question is here.
I followed some advice from a comment that suggested a kind of "DoEvents" style workaround. I know this isn't ideal but I only have a few hours to add busy indicators to about 50 windows and they all have lots of code on the UI thread that I do not have the time to mod开发者_如何学JAVAify to use background threads (I expect to be up all night sorting it without that additional headache).
So, after I set the "Busy" property in my viewmodels I run the following DoEvents style code:
Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new Action(delegate { }));
Now, when I click the button that starts the long-running process, the wait indicator appears as I need it to and all is well. However, the button in question is the default button in the window. If I press Enter, the same command binding is used and I can see in debug mode that the code is visited in exactly the same way. However, the busy indicator doesn't show.
Can anyone suggest a workaround that will allow me to get some sleep tonight?
If you accept to use the "standard" Windows waiting cursor, you can simply set the Cursor property of your Window to Cursors.Wait when starting an operation and then to null at the end of the long-running operation (or use the Mouse.OverrideCursor).
I wrap this in an IDisposable class:
/// <summary>
/// Helper to display a wainting cursor for the whole application
/// </summary>
public class WaitingCursor : IDisposable {
private Cursor m_currentCursor;
public WaitingCursor() {
Enable();
}
/// <summary>
/// Sets the cursort to the waiting cursor
/// </summary>
public void Enable() {
m_currentCursor = Mouse.OverrideCursor;
Mouse.OverrideCursor = Cursors.Wait;
}
/// <summary>
/// Restores the cursor to the default one
/// </summary>
public void Disable() {
Mouse.OverrideCursor = m_currentCursor;
}
#region Implementation of IDisposable
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose() {
Disable();
}
#endregion
}
Then, one can simply write:
using (new WaitingCursor()) {
... // long-running op
}
精彩评论