Enable the "Disable Save" button during validation using IDataErrorInfo

How to disable / enable a button when checking with IDataErrorInfo ?

I am using MVVM using GalaSoft light Framework. In my Model class, I implemented IDataErrorInfo to display error messages.

 public string this[string columnName] { get { Result = null; if (columnName == "FirstName") { if (String.IsNullOrEmpty(FirstName)) { Result = "Please enter first name"; } } else if (columnName == "LastName") { if (String.IsNullOrEmpty(LastName)) { Result = "Please enter last name"; } } else if (columnName == "Address") { if (String.IsNullOrEmpty(Address)) { Result = "Please enter Address"; } } else if (columnName == "City") { if (String.IsNullOrEmpty(City)) { Result = "Please enter city"; } } else if (columnName == "State") { if (State == "Select") { Result = "Please select state"; } } else if (columnName == "Zip") { if (String.IsNullOrEmpty(Zip)) { Result = "Please enter zip"; } else if (Zip.Length < 6) { Result = "Zip length has to be at least 6 digits!"; } else { bool zipNumber = Regex.IsMatch(Zip, @"^[0-9]*$"); if (zipNumber == false) { Result = "Please enter only digits in zip"; } } } else if (columnName == "IsValid") { Result = true.ToString(); } return Result; } } 

Screenshot: http://i.stack.imgur.com/kwEI8.jpg

How to disable / enable the save button. Please suggest?

thanks

+8
c # wpf mvvm light
source share
3 answers

Josh Smith Way is to create the following methods in a model:

 static readonly string[] ValidatedProperties = { "Foo", "Bar" }; /// <summary> /// Returns true if this object has no validation errors. /// </summary> public bool IsValid { get { foreach (string property in ValidatedProperties) { if (GetValidationError(property) != null) // there is an error return false; } return true; } } private string GetValidationError(string propertyName) { string error = null; switch (propertyName) { case "Foo": error = this.ValidateFoo(); break; case "Bar": error = this.ValidateBar(); break; default: error = null; throw new Exception("Unexpected property being validated on Service"); } return error; } 

ViewModel then contains the CanSave property, which reads the IsValid property on the model:

 /// <summary> /// Checks if all parameters on the Model are valid and ready to be saved /// </summary> protected bool CanSave { get { return modelOfThisVM.IsValid; } } 

Finally, if you use RelayCommand , you can set the command predicate to the CanSave property, and the view will automatically enable or disable this button. In ViewModel:

 /// <summary> /// Saves changes Command /// </summary> public ICommand SaveCommand { get { if (_saveCommand == null) _saveCommand = new RelayCommand(param => this.SaveChanges(), param => this.CanSave); return _saveCommand; } } 

And in the view:

 <Button Content="Save" Command="{Binding Path=SaveCommand}"/> 

What is it!

PS: If you haven’t read the article by Josh Smith, it will change your life.

+17
source share

you can add the addition of the boolean CanSave property and set it at the end of your validation method. Associate IsEnabled with your button on IsValid. Something like that:

 public bool CanSave { get{ return canSave; } set{ canSave = value; RaisePropertyChanged( "CanSave" ); } } private bool canSave; public string this[string columnName] { //.... CanSave = Result == String.Empty; } //xaml <Button IsEnabled={Binding Path=CanSave}>Save</Button> 
+8
source share

Here is my way to do this using a combination of the IDataErrorInfo interface, the ValidationErrors dictionary, and the MVVM-Light messaging system. Straight ahead and works like a charm:

Model class

 public Dictionary<string, string> ValidationErrors = new Dictionary<string, string>(); public string this[string columnName] { get { // Remove Property error from ValidationErrors prior to any validation ValidationErrors.Remove(propertyName); //---------------------------------------- string Result = null; if (columnName == "FirstName") { if (String.IsNullOrEmpty(FirstName)) { // Add Property error to ValidationErrors Dic ValidationErrors[propertyName] = Result = "Please enter first name"; //---------------------------------------- } } else if (columnName == "LastName") { if (String.IsNullOrEmpty(LastName)) { // Add Property error to ValidationErrors Dic ValidationErrors[propertyName] = Result = "Please enter last name"; //---------------------------------------- } } // Send MVVM-Light message and receive it in the Code Behind or VM Messenger.Default.Send<PersonInfoMsg>(new PersonInfoMsg()); //---------------------------------------- return Result; } } 

View code behind

  public partial class PersonInfoView : UserControl { public PersonInfoView() { InitializeComponent(); Messenger.Default.Register<PersonInfoMsg>(this, OnErrorMsg); } private void OnErrorMsg(PersonInfoMsg) { // In case of DataGrid validation foreach (PersonInfoModel p in GridName.ItemsSource) { if (p.ValidationErrors.Count == 0) SaveBtn.IsEnabled = true; else SaveBtn.IsEnabled = false; } } } 
+1
source share

All Articles