The correct way to work with buttons is to implement the ICommand interface. Here is an example from my solution:
public class RelayCommand : ICommand { readonly Action<object> _execute; readonly Predicate<object> _canExecute; public RelayCommand(Action<object> execute) : this(execute, null) { } public RelayCommand(Action<object> execute, Predicate<object> canExecute) { if (execute == null) throw new ArgumentNullException("execute"); _execute = execute; _canExecute = canExecute; } #region ICommand Members public bool CanExecute(object parameter) { return _canExecute == null ? true : _canExecute(parameter); } public void Execute(object parameter) { _execute(parameter); } public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } #endregion }
You can then attach the following command to this button:
<Button Command="{Binding MyCommand}" .../>
It remains to declare the ICommand property on your view model:
public ICommand MyCommand { get; private set; }
The button state is automatically updated with most changes. If for some reason this is not the case, you can force the update by calling CommandManager.InvalidateRequerySuggested
source share