WPF / XAML - DataTriggers在选中单选按钮时设置ValidatesOnDataErrors = false / true

时间:2011-08-19 15:13:50

标签: wpf xaml mvvm triggers

我正在开发一个使用DataAnnotations实现MVVM设计模式的应用程序。该应用程序是动态生成的页面列表。在其中一个页面上,我有10个必填字段,其中2个是/否单选按钮。这10个字段分为两组,每组都有边框标记。每个边框的可见性都与隐藏/可见的单选按钮绑定。

我的问题是,如果选择了是,并且显示了相关的5个必需文本框,我如何将ValidatesOnDataErrors设置为false / true并清除其他隐藏的所需TextBox的文本框值?

以下是代码段。

感谢

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

2 个答案:

答案 0 :(得分: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>

答案 1 :(得分: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");
    }
相关问题