开发者

WPF/XAML - DataTriggers to set ValidatesOnDataErrors = false/true when a radio button is checked

开发者 https://www.devze.com 2023-03-29 02:07 出处:网络
I am working on an application that implements the MVV开发者_Python百科M design pattern with DataAnnotations. The application is a dynamically generated list of pages. On one of those pages, I have 10

I am working on an application that implements the MVV开发者_Python百科M design pattern with DataAnnotations. The application is a dynamically generated list of pages. On one of those pages, I have 10 required fields with 2 yes/no radio buttons. Those 10 fields are divided into two groups and each group is wwapped with a border tag. Each border's visibility is bound with the radio buttons for hidden/visible.

My question is if yes was selected and the related 5 required text boxes are displayed how can i set the ValidatesOnDataErrors to false/true and clear the text boxes values of the other hidden required TextBoxes?

Here is a code Snippet.

thanks

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


Try setting the Validation.Template to {x:Null} if it shouldn't show the Validation Error

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


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

精彩评论

暂无评论...
验证码 换一张
取 消