If I’m starting from scratch with writing some kind of view model classes then I often find myself implementing INotifyPropertyChanged in some class like;
public abstract class ViewModelBase : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] String propertyName = null) { if (object.Equals(storage, value)) return false; storage = value; this.OnPropertyChanged(propertyName); return true; } protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { var eventHandler = this.PropertyChanged; if (eventHandler != null) { eventHandler(this, new PropertyChangedEventArgs(propertyName)); } } }
but then I often want commands and I find defining commands to be tedious. Let’s say I’ve got some implementaton of ICommand like this;
class SimpleCommand : ICommand { public event EventHandler CanExecuteChanged; public SimpleCommand(Action action) { this._action = action; } public bool CanExecute(object parameter) { return (true); } public void Execute(object parameter) { if (this._action != null) { this._action(); } } Action _action; }
then I often want a base class that represents a source of a number of commands – e.g. here where I’ve encapsulated the SimpleCommand inside of this CommandableViewModelBase class;
public abstract class CommandableViewModelBase : ViewModelBase { class SimpleCommand : ICommand { public event EventHandler CanExecuteChanged; public SimpleCommand(Action action) { this._action = action; } public bool CanExecute(object parameter) { return (true); } public void Execute(object parameter) { if (this._action != null) { this._action(); } } Action _action; } public CommandableViewModelBase() { this.commands = new Dictionary<string, ICommand>(); } protected void AddCommand(string name, Action handler) { this.commands.Add(name, new SimpleCommand(handler)); } public IReadOnlyDictionary<String, ICommand> Commands { get { return (this.commands); } } Dictionary<string, ICommand> commands; }
and then I can write a view model class derived from this;
public class ViewModel : CommandableViewModelBase { public ViewModel() { base.AddCommand("invoke", OnInvoke); } void OnInvoke() { } }
and bind it up;
<Button Content="Hello" Command="{Binding Path=Commands[invoke]}" />
it’s just something that I find myself doing from time to time so thought I’d share. That kind of binding is a little “opaque” in terms of being able to build up those expressions graphically by pointing and clicking inside of Visual Studio or Blend so sometimes I’ll also add a specific property InvokeCommand which reaches into the dictionary in the parent class just to make it easier to use the tooling. It could be taken a lot further – e.g. those commands aren’t observable but that’d be easy enough to fix.