Changing the cursor in WPF sometimes works, sometimes doesn't Changing the cursor in WPF sometimes works, sometimes doesn't wpf wpf

Changing the cursor in WPF sometimes works, sometimes doesn't


Do you need the cursor to be a "wait" cursor only when it's over that particular page/usercontrol? If not, I'd suggest using Mouse.OverrideCursor:

Mouse.OverrideCursor = Cursors.Wait;try{    // do stuff}finally{    Mouse.OverrideCursor = null;}

This overrides the cursor for your application rather than just for a part of its UI, so the problem you're describing goes away.


One way we do this in our application is using IDisposable and then with using(){} blocks to ensure the cursor is reset when done.

public class OverrideCursor : IDisposable{  public OverrideCursor(Cursor changeToCursor)  {    Mouse.OverrideCursor = changeToCursor;  }  #region IDisposable Members  public void Dispose()  {    Mouse.OverrideCursor = null;  }  #endregion}

and then in your code:

using (OverrideCursor cursor = new OverrideCursor(Cursors.Wait)){  // Do work...}

The override will end when either: the end of the using statement is reached or; if an exception is thrown and control leaves the statement block before the end of the statement.

Update

To prevent the cursor flickering you can do:

public class OverrideCursor : IDisposable{  static Stack<Cursor> s_Stack = new Stack<Cursor>();  public OverrideCursor(Cursor changeToCursor)  {    s_Stack.Push(changeToCursor);    if (Mouse.OverrideCursor != changeToCursor)      Mouse.OverrideCursor = changeToCursor;  }  public void Dispose()  {    s_Stack.Pop();    Cursor cursor = s_Stack.Count > 0 ? s_Stack.Peek() : null;    if (cursor != Mouse.OverrideCursor)      Mouse.OverrideCursor = cursor;  }}


You can use a data trigger (with a view model) on the button to enable a wait cursor.

<Button x:Name="NextButton"        Content="Go"        Command="{Binding GoCommand }">    <Button.Style>         <Style TargetType="{x:Type Button}">             <Setter Property="Cursor" Value="Arrow"/>             <Style.Triggers>                 <DataTrigger Binding="{Binding Path=IsWorking}" Value="True">                     <Setter Property="Cursor" Value="Wait"/>                 </DataTrigger>             </Style.Triggers>         </Style>    </Button.Style></Button>

Here is the code from the view-model:

public class MainViewModel : ViewModelBase{   // most code removed for this example   public MainViewModel()   {      GoCommand = new DelegateCommand<object>(OnGoCommand, CanGoCommand);   }   // flag used by data binding trigger   private bool _isWorking = false;   public bool IsWorking   {      get { return _isWorking; }      set      {         _isWorking = value;         OnPropertyChanged("IsWorking");      }   }   // button click event gets processed here   public ICommand GoCommand { get; private set; }   private void OnGoCommand(object obj)   {      if ( _selectedCustomer != null )      {         // wait cursor ON         IsWorking = true;         _ds = OrdersManager.LoadToDataSet(_selectedCustomer.ID);         OnPropertyChanged("GridData");         // wait cursor off         IsWorking = false;      }   }}