I have to use this Command in a WPF application (i dont like it really but if i have to -> i have to ):
http://wpftutorial.net/DelegateCommand.html
But the main problem I have here is that I don t want to have in nearly every line of my code a call to the
RaiseCanExecuteChanged()
method. So what could I do to do that auto like RoutedUICommand does.
I have a lot of databindings and as example if Foo.FooProp != null Command can execute. But I want as less code as possible and so I would have to register events everywhere or update commands all over my application....
You could implement a form of DelegateCommand
which invokes the delegates added to CanExecuteChanged
everytime there is a change of possible consequence in the UI. This example uses CommandManager.RequerySuggested
.
public class AutoDelegateCommand : DelegateCommand, ICommand
{
public AutoDelegateCommand(Action<object> execute)
: base(execute)
{
}
public AutoDelegateCommand(Action<object> execute, Predicate<object> canExecute)
: base(execute, canExecute)
{
}
event EventHandler ICommand.CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
}
I think I've seen an example like this before, perhaps in the MVVMLight toolkit?
When I use a DelegateCommand
, I just manually raise the CanExecuteChanged
in the PropertyChange
event whenever a property the command relies on changes.
Here's an example I did a few days ago where the CanExecute
was based off the IsLoading
and IsValid
properties:
public MyViewModel()
{
this.PropertyChanged += MyViewModel_PropertyChanged;
}
void MyViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case "IsLoading":
case "IsValid":
((DelegateCommand)MyCommand).RaiseCanExecuteChanged();
break;
}
}
public ICommand MyCommand
{
get
{
if (_myCommand == null)
_myCommand = new DelegateCommand(Run, CanRun);
return _myCommand;
}
}
public bool CanRun()
{
return this.IsValid && !IsLoading;
}
I find this keeps the logic easy to follow and maintain, and it only checks the CanExecuteChanged()
method when the relevant properties change.