2014-01-10 67 views
1

我在我的實體類中使用IDataErrorInfo來驗證實體對象。我有這個工作,並顯示任何使用Validation.ErrorTemplate的每個控件所需的視覺樣式的驗證問題。WPF IDataErrorInfo HasError和必填字段的不同控制樣式

例如一個TextBox控件我使用Validation.ErrorTemplate來裝飾帶有紅色邊框的文本框和帶有描述驗證錯誤的工具提示的感嘆號圖標。

現在我想稍微軟化UI的外觀。當用戶打開數據輸入表單時,我想將所需字段的背景顏色更改爲淺藍色。我不想使用帶有紅色邊框和感嘆號的Validation.ErrorTemplate,直到他們至少在沒有驗證的文本框中輸入一些數據。

我想保留實體類中的驗證和必需的字段邏輯,並保持UI聲明。是否有我可以使用的模式或另一個類,我需要查看此功能?我正在用Validation.HasError和MultiValueConveter中的TextBox樣式使用DataTrigger來檢查我是否有驗證錯誤,並且控件的值是null或空字符串,但沒有很多運氣,似乎應該是一個更簡單的方法。

例如,實現IDataErrorInfo的實體類返回驗證錯誤,例如如果電子郵件屬性爲空或空,並且另一個驗證錯誤,例如「需要電子郵件地址」當Email屬性設置爲不驗證爲有效電子郵件地址的字符串時,「電子郵件地址的格式不正確」。如果Email屬性設置爲null或空,我只想將Background設置爲LightBlue。如果Email屬性中有一個字符串,但它不是一個有效的電子郵件地址,我想顯示Validation.ErrorTemplate。

編輯

public class MyEntity : IDataErrorInfo 
{ 
    private static readonly IList<PropertyInfo> BindableProperties; 

    static MyEntity() 
    { 
     BindableProperties = typeof(MyEntity).GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.CanRead && p.CanWrite).ToList(); 
    } 

    public string Email { get; set; } 

    public Boolean IsValid() 
    { 
     return BindableProperties.All(p => this[p.Name] == null); 
    } 

    #region // IDataErrorInfo Members 

    public string this[string name] 
    { 
     get 
     { 
      string message = null; 

      switch (name) 
      { 
       ... 

       case "Email": 

        if (!string.IsNullOrEmpty(Email)) 
        { 
         try 
         { 
          new System.Net.Mail.MailAddress(Email); 
         } 
         catch 
         { 
          message = "Email does not appear to be a valid email address."; 
          break; 
         } 
        } 
        else 
        { 
         message = "Email is required"; 
        } 

        break; 

       ... 
      } 

      return message; 
     } 
    } 

    public string Error 
    { 
     get { throw new NotImplementedException(); } 
    } 

    #endregion // IDataErrorInfo Members 
} 

控制XAML

<TextBox Name="EmailTextBox" Text="{Binding MyEntity.Email, ValidatesOnDataErrors=True}"/> 

<Button x:Name="SaveButton" Command="Save" Content="Save"> 
    <Button.CommandBindings> 
     <CommandBinding Command="Save" Executed="Save_Executed" CanExecute="Save_CanExecute"/> 
    </Button.CommandBindings> 
</Button> 

代碼隱藏

private void Save_CanExecute(object sender, CanExecuteRoutedEventArgs e) 
{ 
    e.CanExecute = MyEntity.IsValid(); 
} 

+0

爲什麼在您打開DataEntry表單時驗證。我認爲你應該設置實體的新實例 – ethicallogics

+0

我正在創建實體的新實例。我在綁定中設置了ValidatesOnDataErrors = True,所以只要更新綁定源,就會顯示Validation.ErrorTemplate – Dude0001

+0

那就是試圖說只有當你在文本框中輸入值時綁定源纔會更新。或者你通過代碼 – ethicallogics

回答

0

試試這個你Entity.Here員工是一個實體。

public class Employee : INotifyPropertyChanged,IDataErrorInfo 
{ 
    private static readonly IList<PropertyInfo> BindableProperties; 

    static Employee() 
    { 
     BindableProperties = typeof(Employee).GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.CanRead && p.CanWrite).ToList(); 
    } 

    string email; 

    public string Email 
    { 
     get { return email; } 
     set { 
      email = value; 
      Validate(true,"Email"); 
      Notify("Email"); 
     } 
    } 

    public Boolean IsValid() 
    { 
     return BindableProperties.All(p => Validate(false,p.Name)); 
    } 

    bool Validate(bool addErrors, string propName) 
    { 
     string message = string.Empty; 

     switch (propName) 
     { 
      case "Email": 
       if (!string.IsNullOrEmpty(Email)) 
       { 
        try 
        { 
         new System.Net.Mail.MailAddress(Email); 
        } 
        catch 
        { 
         message = "Email does not appear to be a valid email address."; 
         break; 
        } 
       } 
       else 
       { 
        message = "Email is required"; 
       } 
       break; 
     } 

     if (addErrors) 
      AddOrRemoveError(propName, message); 

     return string.IsNullOrEmpty(message); 
    } 

    void AddError(string propertyName, string error) 
    { 
     if (!errors.ContainsKey(propertyName)) 
      errors.Add(propertyName, error); 
    } 

    void RemoveError(string propertyName) 
    { 
     if (errors.ContainsKey(propertyName)) 
      errors.Remove(propertyName); 
    } 

    void AddOrRemoveError(string propName,string message) 
    { 
     if (!string.IsNullOrEmpty(message)) 
      AddError(propName, message); 
     else 
      RemoveError(message); 
    } 

    private Dictionary<string, string> errors = new Dictionary<string, string>(); 

    public event PropertyChangedEventHandler PropertyChanged; 

    void Notify(string propName) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(propName)); 
    } 

    public string Error 
    { 
     get { throw new NotImplementedException(); } 
    } 

    public string this[string columnName] 
    { 
     get { if(errors.ContainsKey(columnName)) return errors[columnName]; else return null;} 
    } 
} 
+0

我喜歡使用無效字段的字典,但是這不處理與數據輸入錯誤字段不同的空白必填字段。 – Dude0001