I’ve a ViewModel class like this in a Prism / WPF project.
public class ContentViewModel : ViewModelBase, IContentViewModel
{
public ContentViewModel(IPersonService personService)
{
Person = personService.GetPerson();
SaveCommand = new DelegateCommand(Save, CanSave);
}
public Person Person { get; set; }
public DelegateCommand SaveCommand { get; set; }
private void Save()
{
// Save actions here...
}
private bool CanSave()
{
return Person.Error == null;
}
}
The person type used in the above ViewModel is defined as follows:
public class Person : INotifyPropertyChanged, IDataErrorInfo
{
private string _firstName;
public string FirstName
{
get { return _firstName; }
set
{
_firstName = value;
OnPropertyChanged("FirstName");
}
}
// other properties are implemented in the same way as above...
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
private string _error;
public string Error
{
get
{
return _error;
}
}
public string this[string columnName]
{
get
{
_error = null;
switch (columnName)
{
// logic here to validate columns...
}
return _error;
}
}
}
An instance of ContentViewModel is set as DataContext of a View. Inside the View I’ve used binding to Person as follows:
<TextBox Text="{Binding Person.FirstName, ValidatesOnDataErrors=True}" />
<Button Content="Save" Command="{Binding SaveCommand}" />
When I make changes to TextBox which is binded to Person’s properties like FirstName and click Save I could see the changes in ViewModel command handler. But if any of these properties fail in validation CanSave is never executed and button never gets disabled.
How do I disable a button based on DelegateCommand’s CanExecute action handler in the above scenario?
try this with all the properties that can change error:
Alternatively
The problem you are having is that the OnPropertyChanged is not being called when the error changes.
The next step is to subscribe to the person’s propertychanged event when its created, and create a handler that checks for the propertychanged and then changes the boolean variable that the command uses.
Hope this works. I built this by hand and didn’t check it so let me know if its buggy or whatever and ill correct it