Posts Tagged ‘ DependencyProperty ’

[WPF] Custom ValidationRule with an additional parameter

Hello,

maybe you ever had the problem that you wanted to create a custom validationrule but you need some kind of an extra parameter.
But it seems that there is no straightforward way to do that.

So I used this workaround in order to achieve that.
In this example I will validate a string. The parameter gives the length if the string is shorter then it is valid else not.

First of all we have to create our custom ValidationRule

public class MyStringLengthValidationRule : ValidationRule
  {
    /// <summary>
    /// Gets or sets the maximal length of the string
    /// </summary>
    public int Length { get; set; }

    /// <summary>
    /// Checks if the string is valied
    /// </summary>
    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
      if (value.ToString().Length <= Length)
         return new ValidationResult(true, null);
      return new ValidationResult(false, "The string is to long");
    }
  }

All right. Here you see this simple ValidationRule with our additional property (Length).
We can not use DependencyProperties because ValidationRule does not extend DependencyObject therefore we have to use this property.

The second step is to assign our ValidationRule to a control

        <TextBox>
            <TextBox.Text>
                <Binding Path="MyText">
                    <Binding.ValidationRules>
                        <utils:MyStringLengthValidationRule Length="{Binding MyLength}" />
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>
        </TextBox>

You may think that it works like this but it does not. Since the Length property is not a DependencyProperty we can not directly bind to it.
But there exists a nice workaround. We can just use a so-called proxy which allows us to bind values to normal properties.
I used the proxy from this blog: http://www.11011.net/wpf-binding-properties

The version using the proxy looks like this

<utils:Proxy In="{Binding MyLength, Mode=OneWay,UpdateSourceTrigger=PropertyChanged}" Out="{Binding ElementName=strLengthValidationRule, Path=Length}" /> 
<TextBox>
  <TextBox.Text>
     <Binding Path="MyText">
         <Binding.ValidationRules>
            <utils:MyStringLengthValidationRule x:Name="strLengthValidationRule" />
          </Binding.ValidationRules>
       </Binding>
  </TextBox.Text>
</TextBox>

All right now it should work.

I attached the demo project. Where you can specify the maximal length (upper TextBox) of the string in the TextBox at the bottom.
Note that the Validation will only be updated when the value of the TextBox was changed!

The attached file is a rar file. I just have to add the doc extension because else I can not upload it.
Change the extension in .rar then you can extract it. (It contains the demo project as a VS 2010 Beta solution)
ValidatorWithParameter.rar (doc)

Advertisements
Advertisements