2011-06-30 29 views
8

如何在使用IDataErrorInfo進行驗證時禁用/啓用按鈕?我使用GalaSoft light Framework使用MVVM。在我的Model類中,我實現了IDataErrorInfo來顯示錯誤消息。啓用在使用IDataErrorInfo進行驗證期間禁用保存按鈕

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's 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; 

    } 
} 

截圖:http://i.stack.imgur.com/kwEI8.jpg

如何禁用/啓用保存按鈕。請建議?

感謝

回答

17

這樣做的Josh Smith Way是創建示範以下方法:

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; 
} 

視圖模型則包含了CanSave屬性讀取模型上的IsValid屬性:

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

最後,如果你正在使用RelayCommand,您可以設置predica te的命令到CanSave屬性,View將自動啓用或禁用該按鈕。在視圖模型:

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

     return _saveCommand; 
    } 
} 

並在視圖:

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

就是這樣! PS:如果你還沒有閱讀Josh Smith的文章,它會改變你的生活。

+0

這不是一種將驗證邏輯放入模型的好方法,因爲驗證邏輯可能會在不同的場景中發生變化。 –

+0

爲簡單起見,它可以是公共布爾IsValid => ValidatedProperties.All(p => GetValidationError(p)== null);'。 – dee

8

你可以新增一個布爾屬性CanSave,並在您的valiation方法結束設置。將IsEnabled從您的按鈕綁定到IsValid。 財產以後這樣的:

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> 
+0

這實際上比公認的答案好得多,如果你使用'IDataErrorInfo'如果您只是使用像我現在這樣的驗證規則屬性,你可能不得不接受已接受的答案:) – GONeale

+5

如果有多個驗證,則不起作用... [str每個屬性都會調用columnName]。因此,如果prop1無效,並且prop2有效,則CanSave設置爲true。 –

+0

@PetervanKekem該部分在'// ....'中:每次調用該函數時,必須根據先前的結果重新計算'Result'。 – stijn

1

下面是我使用IDataErrorInfo接口,ValidationErrors Dictionary和MVVM-Light消息系統的組合的方式。直線前進和作品般的魅力:

模型類

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; 
    } 
} 

查看代碼背後

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; 
     } 
    } 
    }