2011-08-19 6 views
3

をチェックすると、私はDataAnnotationsとMVVMデザインパターンを実装したアプリケーションに取り組んでいます。アプリケーションは動的に生成されたページのリストです。これらのページの1つに、2つのはい/いいえラジオボタン付きの必須フィールドが10つあります。これらの10のフィールドは2つのグループに分けられ、各グループは境界タグでwwappedされます。各ボーダーの可視性は、非表示/非表示のラジオボタンにバインドされています。WPF/XAML - ValidatesOnDataErrorsを設定するDataTriggers =真/偽のラジオボタンが

質問が選択され、関連する5つの必須テキストボックスが表示されます。ValidatesOnDataErrorsをfalse/trueに設定し、その他の非表示の必須TextBoxesのテキストボックス値をクリアするにはどうすればよいですか?ここで

は、コードスニペットです。

おかげ

<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'値を再バインドしていない検証エラーを表示してはならない場合{x:Null}Validation.Templateを設定してみてくださいあなたのトリガの 'ValidatesOnDataErrors'? – Rachel

+0

私はそれを試み、それは仕事をしなかった。問題はValidatesOnDataErrorsたらTrueに設定し、私は ValidatesOnDataErrorsでそれを再バインドしようとする= FalseのかValidatesOnDataErrorsアウトまたは私は何にバインドいけない場合でも、それは検証を削除しないdosntされていることです。ここに私のプロパティがどのように見えるかです:[必須(にErrorMessage = "!必須フィールド")] パブリック文字列JobTitle { { リターンを_jobTitle取得します。 }は{ _jobTitle =値を設定します。 BindingSourceが変更されていないので、おそらくそれは、UIを更新していない }} おかげで、 – Bobby

+0

。プロパティの再バインドに加えて、 'RadioButton'が変更されたときにViewModelの' PropertyChanged'イベントを発生させてみてください。 – Rachel

答えて

1

それは

<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

関連する問題