2011-08-19 29 views
3

我正在使用DataAnnotations實現MVVM設計模式的應用程序。該應用程序是一個動態生成的頁面列表。在其中一頁上,我有10個必填字段,其中有2個是/否單選按鈕。這10個字段分成兩組,每組用邊界標籤wwapped。每個邊框的可見性都與隱藏/可見的單選按鈕綁定。當單選按鈕被選中時,WPF/XAML - DataTriggers設置ValidatesOnDataErrors = false/true

我的問題是,如果選擇是,並顯示相關的5個必需的文本框我怎樣才能將ValidatesOnDataErrors設置爲false/true並清除其他隱藏所需文本框的文本框的值?

這裏是一個代碼片段。

感謝

<Border> 
<Border.Style> 
    <Style> 
    <Setter Property="Border.Visibility" Value="Hidden"></Setter> 
    <Style.Triggers> 
    <DataTrigger Binding="{Binding ElementName=PresentlyEmployed_yes, Path=IsChecked}" 
        Value="True"> 
     <Setter Property="Border.Visibility" Value="Visible"></Setter> 
    </DataTrigger> 
    </Style.Triggers> 
    </Style> 
    </Border.Style> 
    <Grid Height="Auto" Width="Auto"> 
    <Label Name="JobTitle" 
       Content="{x:Static properties:Resources.JobTitlelbl}" /> 
    <TextBox Name="JobTitle" Text="{Binding JobTitle, Mode=TwoWay, 
    ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}"> 
    <TextBox.Style> 
     <Style TargetType="{x:Type TextBox}"> 
     <Setter Property="Text" Value="{Binding PrimaryInsuredBusinessDuties, Mode=TwoWay, 
      UpdateSourceTrigger=PropertyChanged, IsAsync=True}" /> 
     <Style.Triggers> 
     <DataTrigger Binding="{Binding ElementName=PresentlyEmployed_yes, Path=IsChecked}" 
      Value="True"> 
     <Setter Property="Text" Value="{Binding JobTitle, Mode=TwoWay, 
      ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}" /> 
     </DataTrigger> 
     <DataTrigger Binding="{Binding ElementName=PresentlyEmployed_yes, Path=IsChecked}" 
     Value="False"> 
     <Setter Property="Text" Value="{Binding JobTitle, Mode=TwoWay, 
      ValidatesOnDataErrors=False, UpdateSourceTrigger=PropertyChanged}"></Setter> 
     </DataTrigger> 
     </Style.Triggers> 
    </Style> 
    </TextBox.Style> 
    </TextBox> 
    </Grid> 
</Border> 
+0

你爲什麼不只是重新綁定'Text'值不觸發器中的ValidatesOnDataErrors? – Rachel

+0

我試過了,它沒有奏效。問題是,一旦ValidatesOnDataErrors設置爲True,我嘗試用 ValidatesOnDataErrors = False重新綁定它,或者無法驗證ValidatesOnDataErrors,或者即使我沒有將它綁定到任何東西,它也不會刪除驗證。這裏是我的財產的樣子: [必需(的ErrorMessage = 「!必填字段」) 公共字符串JOBTITLE { 得到 { 回報_jobTitle; } set { _jobTitle = value; } } 謝謝, – Bobby

+0

也許它沒有更新UI,因爲BindingSource沒有更改。除了重新綁定屬性外,當RadioButton改變時,嘗試在ViewModel中引發'PropertyChanged'事件。 – Rachel

回答

1

嘗試Validation.Template設置爲{x:Null}如果它不應該顯示驗證錯誤

<StackPanel> 
    <ListBox x:Name="MyListBox" SelectedIndex="0"> 
     <ListBoxItem>Validate Value 1</ListBoxItem> 
     <ListBoxItem>Validate Value 2</ListBoxItem> 
    </ListBox> 

    <TextBox Text="{Binding Value1, ValidatesOnDataErrors=True}"> 
     <TextBox.Style> 
      <Style TargetType="{x:Type TextBox}"> 
       <Style.Triggers> 
        <DataTrigger Binding="{Binding SelectedIndex, ElementName=MyListBox}" Value="1" > 
         <Setter Property="Validation.ErrorTemplate" Value="{x:Null}" /> 
        </DataTrigger> 
       </Style.Triggers> 
      </Style> 
     </TextBox.Style> 
    </TextBox> 
    <TextBox Text="{Binding Value2, ValidatesOnDataErrors=True}"> 
     <TextBox.Style> 
      <Style TargetType="{x:Type TextBox}"> 
       <Style.Triggers> 
        <DataTrigger Binding="{Binding SelectedIndex, ElementName=MyListBox}" Value="0" > 
         <Setter Property="Validation.ErrorTemplate" Value="{x:Null}" /> 
        </DataTrigger> 
       </Style.Triggers> 
      </Style> 
     </TextBox.Style> 
    </TextBox> 
</StackPanel> 
+0

這不會顯示UI上的錯誤,但是,該頁面仍然無效,這意味着由於JobTitle屬性需要字段驗證,所以我仍然無法觸發nextCommand。 – Bobby

+0

難道你不能改變你的'IsValid'代碼來檢查基於哪個'RadioButton'被選中的特定屬性的驗證嗎? – Rachel

+0

這就是我現在擁有它的方式。在我的ValidationViewModelBase類中,我繼承了IDataErrorInfo和IValidationExceptionHandler。我通過添加或刪除基於傳遞的屬性名稱的字段驗證來篩選「this」方法中的validationAttribute列表。然而,這個應用程序有超過500個字段,所以驗證基類目前看起來很難看。 – Bobby

0
Sure, here is how my validationbase class looks like (Simplified) 

    public class ValidationViewModelBase : ViewModelBase, IDataErrorInfo, IValidationExceptionHandler 
    { 
    private Dictionary<string, Func<ValidationViewModelBase, object>> _propertyGetters; 
    private Dictionary<string, ValidationAttribute[]> _validators; 

    /// <summary> 
    /// Gets the error message for the property with the given name. 
    /// </summary> 
    /// <param name="propertyName">Name of the property</param> 
    public string this[string propertyName] 
    { 
     IList<string> fieldsNames = new List<string>(); 
    { 
    if (propertyName == "PresentlyEmployed") 
     { 
     //if its true then 
     fieldsNames.Add("JobTitle"); 

     AddFieldsValidation(fieldsNames); 
     }else{ 

     fieldsNames.Add("EmploymentAddress"); 

     RemoveValidation(fieldsNames); 
    } 

    if (this.propertyGetters.ContainsKey(propertyName)) 
     { 
      var propertyValue = this.propertyGetters[propertyName](this); 
     var errorMessages = this.validators[propertyName] 
         .Where(v => !v.IsValid(propertyValue)) 
         .Select(v => v.ErrorMessage).ToArray(); 
     return string.Join(Environment.NewLine, errorMessages); 
     } 
    return string.Empty; 
    } 

    /// <summary> 
    /// Gets an error message indicating what is wrong with this object. 
    /// </summary> 
    public string Error 
    { 
     get 
     { 
     var errors = from validator in this.validators 
         from attribute in validator.Value 
      where !attribute.IsValid(this.propertyGetters[validator.Key](this)) 
      select attribute.ErrorMessage; 

      return string.Join(Environment.NewLine, errors.ToArray()); 
      } 
     } 

    } 

    /// <summary> 
    /// Gets the number of properties which have a validation attribute and are currently valid 
    /// </summary> 
    public int ValidPropertiesCount 
    { 
     get 
     { 
      var query = from validator in this.validators 
       where validator.Value.All(attribute => attribute.IsValid(this.propertyGetters[validator.Key](this))) 
       select validator; 

      var count = query.Count() - this.validationExceptionCount; 
      return count; 
      } 
     } 
} 

/// <summary> 
    /// Gets the number of properties which have a validation attribute 
    /// </summary> 
    public int TotalPropertiesWithValidationCount 
    { 
     get 
     { 
      return this.validators.Count(); 
     } 
    } 

public ValidationViewModelBase() 
    { 
     this.validators = this.GetType() 
      .GetProperties() 
      .Where(p => this.GetValidations(p).Length != 0) 
      .ToDictionary(p => p.Name, p => this.GetValidations(p)); 

     this.propertyGetters = this.GetType() 
      .GetProperties() 
      .Where(p => this.GetValidations(p).Length != 0) 
      .ToDictionary(p => p.Name, p => this.GetValueGetter(p)); 
    } 

private ValidationAttribute[] GetValidations(PropertyInfo property) 
    { 
     return (ValidationAttribute[])property.GetCustomAttributes(typeof(ValidationAttribute), true); 
    } 

    private Func<ValidationViewModelBase, object> GetValueGetter(PropertyInfo property) 
    { 
     return new Func<ValidationViewModelBase, object>(viewmodel => property.GetValue(viewmodel, null)); 
    } 

    private int validationExceptionCount; 

    public void ValidationExceptionsChanged(int count) 
    { 
     this.validationExceptionCount = count; 
     this.OnPropertyChanged("ValidPropertiesCount"); 
    } 
+0

@Rachel:上面的代碼目前正在完成這項工作。但是,我並不爲我添加或刪除字段的方式感到自豪。所以我認爲DataTriggers可以爲我完成這項工作。如果你有不同的方法,請讓我知道。 謝謝 – Bobby

相關問題