A lot of the answers on here are old and I'm not sure they are current any more. Here is how I did it using RelayCommand. I have a save Save button in .xaml tied to an instance of a relay command class in the viewmodel. The relay command also accepts an argument that can be bound to in the xaml to pass a reference to the view object. When a property in the viewmodel changes I call SaveCommand.RaiseCanExecuteChanged();
to ge the button to execute it's CanSave longic.
Here is the viewmodel:
namespace Projectname.viewmodels
{
internal class addressPointVM : INotifyPropertyChanged, IDataErrorInfo
{
public addressPointVM() {
SaveCommand = new RelayCommand<object>((parms) => DoSave(parms), parms => CanISave());
}
private bool CanISave()
{
return CanSave;
}
private void DoSave(object parms)
{
//ProWindow is my view that is calling the command
(parms as ProWindow).DialogResult = true;
(parms as ProWindow).Close(); ;
}
public RelayCommand<object> SaveCommand { get; private set;
private bool _canSave = false;
//other elements alter this property and then call SaveCommand.RaiseCanExecuteChanged()
public bool CanSave
{
get
{
return _canSave;
}
set
{
if (_canSave == value) return;
_canSave = value;
}
}
}
}
Here is the relaycommand class
public class RelayCommand<T> : ICommand
{
Action<T> _TargetExecuteMethod;
Func<T, bool> _TargetCanExecuteMethod;
public RelayCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod)
{
_TargetExecuteMethod = executeMethod;
_TargetCanExecuteMethod = canExecuteMethod;
}
public void RaiseCanExecuteChanged()
{
CanExecuteChanged(this, EventArgs.Empty);
}
bool ICommand.CanExecute(object parameter)
{
if (_TargetCanExecuteMethod != null)
{
T tparm = (T)parameter;
return _TargetCanExecuteMethod(tparm);
}
if (_TargetExecuteMethod != null)
{
return true;
}
return false;
}
public event EventHandler CanExecuteChanged = delegate { };
void ICommand.Execute(object parameter)
{
if (_TargetExecuteMethod != null)
{
_TargetExecuteMethod((T)parameter);
}
}
}
And Finally here is the xaml:
<Button Command="{Binding SaveCommand}" Style="{DynamicResource Esri_Button}" CommandParameter="{Binding ElementName=AddAddressPointWin}" Content="Save" Margin="5"/>