I am at the stage in a project where I need to get control of enabling / disabling some hyperlinks based on various business rules. I noticed all topics on RaiseCanExecuteChanged event refer to MVVM light. Does this mean that I have to use MVVM light or is there a way to access this event using standard MVVM. If so, how? Thanks
Asked
Active
Viewed 1,144 times
1 Answers
2
ICommands have an event that command watchers subscribe to. When this event fires, it is the responsibility of the watchers (Button, etc) to call CanExecute in order to determine if they should enable/disable themselves.
As you must implement ICommand, you must also provide a way for your ViewModels (or whatever, depending on your design) to fire this event from outside the ICommand instance. How you go about this is up to you. It is common (in my experience) to place a method on your ICommand implementation called something like FireCanExecuteChanged
which you can call to inform the instance that they should fire the CanExecute event.
Here's an example in vaguely c#-like pseudocode.
public sealed class MyViewModel
{
// dependencyproperty definition left off for brevity
public MyCommand ACommand {get;private set;}
// fired when some DP changes which affects if ACommand can fire
private static void OnSomeDependencyPropertyChanged
(object sender, EventArgs e)
{
(sender as MyViewModel).ACommand.FireCanExecuteChanged();
}
}
public sealed class MyCommand : ICommand
{
public event EventHandler CanExecuteChanged;
public bool CanExecute(object arg) { return arg != null; }
public void Execute(object arg) { throw new NotImplementedException(); }
public void FireCanExecuteChanged() {
CanExecuteChanged(this, EventArgs.Empty); }
}
-
My implementation of the ICommand includes a event handler: CanExecuteChanged. As an example,if I had a command called GetListCommand = new DelegateCommand (LoadList,CanLoadList)... how would I fire the CanExecuteChanged event? – Greg May 18 '11 at 18:54
-
@greg: `public void FireCanExecuteChanged(){ CanExecuteChanged(this, EventArgs.Empty); }` is a very simple implementation (which will probably throw a NullReferenceException occasionally) – May 18 '11 at 19:02
-
Ok, and what calls the FireCanExecuteChanged ? – Greg May 18 '11 at 19:09
-
@greg: The ViewModel on which the ICommand is situated. Its the ViewModel that knows its internal state, and knows when a particular command's CanExecute value has changed. – May 18 '11 at 19:25
-
Sorry, I understand your explanation but Im not sure of the coding. In my example above, I cannot use GetListCommand.FireCanExecuteChanged() and neither can I call FireExecuteChanged(). Could you give me an example - thanks – Greg May 18 '11 at 19:35
-
@greg: Updated with crappy example. – May 18 '11 at 20:14
-
Thanks - now I understand where the bits go. – Greg May 19 '11 at 08:43
-
@greg: lol forgot the FireCanExecuteChanged method in the ICommand. Glad you understand what I was talking about better, now. I don't know if this is exactly the best pattern, but it is one I've seen used most often. I've heard talk about promoting commands to be a first level entity in MVVM (MVCVM?) where logic for specific commands is encapsulated in them, rather than in the ViewModel, but I haven't seen any examples or have found any uses that switches on that lightbulb, if you know what I mean. – May 19 '11 at 13:52