How to intercept execution of a RoutedCommand within the view?
Asked Answered
S

1

7

In a WPF / MVVM application, I am trying to find a code-efficient way to set the main view cursor to Cursors.Wait prior to any lengthy operation and to restore it to the default cursor after completion.

Since all operations are invoked using routed commands, I'd like to find a way of intercepting command execution, ideally by creating a generic command class that wraps an instance of a built-in routed command, but I can't visualize how to do this.

Specifically, the RoutedCommand.Execute method is not virtual so I need another mechanism to intercept its calls. Also, I am not sure how an instance of the generic command class would reference the view for which it has to set the cursor.

Any advice please?

Slapbang answered 7/7, 2010 at 10:32 Comment(2)
There may very well be a reason that you want to do this, which sounds somewhat complicated, but is there a reason you can't simply create a CurrentCursor property in your ViewModel, and bind the cursor in your View(s) to that property?Partlet
@Wonko. Thanks - that's a good question and I agree that it seems like the most MVVM-compliant approach. However, it means that I will have to apply the same 2-line code change to many ViewModel methods, whereas I was hoping to centralize the cursor management code. A second complication is that my View contains some controls that accept routed commands. How do I apply the same logic to their operations, since they are not part of the ViewModel?Slapbang
T
3

You can set the Cursor in a static manner. The effect is that the cursor will be 'Wait' while the app has focus rather than when it is over a certain control.

The code, which would be part of the ViewModel at the start of the lengthy operation:

Mouse.OverrideCursor = Cursors.Wait;

After the operation is complete you have to clear the override like this:

Move.OverrideCursor = null;
Townscape answered 12/7, 2010 at 4:45 Comment(3)
thanks for your idea and +1 for teaching me something new and useful, but it still doesn't really solve the issues that I raised in my comment to @Wonko.Slapbang
An alternative here is to create your own implementation of ICommand. A popular one is called a RelayCommand, which I'm sure you can find implemented online somewhere. If you use it for your commands then you can abstract away this cursor handling in the base-type's 'execute' handling. To my knowledge there is no way to globally intercept all routed commands. The only downside would be that your commands aren't 'routed' anymore. Instead they are pushed to the ViewModel. Hope that helps.Townscape
Thanks again Steven. That's exactly the kind of thing I am trying to achieve although I guess I need to think about whether I can live without the commands being routed. I am struggling to visualize how this would work in the case of built-in commands that target controls (e.g the ToggleBold command that targets RichTextBox). Is there a way to get this scenario to work with RelayCommand?Slapbang

© 2022 - 2024 — McMap. All rights reserved.