[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
    • racingwastl
    • July 29th, 2010

    Special thanks for this post! It works great!

    • JKatz
    • November 23rd, 2010

    Another thanks for posting this! I have just finished implementing it and it works beautifully.

    • Shady
    • April 18th, 2011

    It is great post, but i faced a problem with your demo the “Length” value equal to “0” at the first run without changing the value of the length in the upper text box
    So to work well, i must change the value for “Length” in the text box to force “NotifyPropertyChanged” event to be fired
    do you have any idea about that ?

      • michlG
      • April 22nd, 2011

      Hi,
      sorry for the late reply but I have not seen your comment.
      The problem is that the validation rule is triggered when the value in the textbox is change.
      Usually it is not necessary to change the Length-Property at runtime.
      As far as I know you have to use the workaround an just fire the PropertyChanged-Event (for the “MyText”-TextBox)
      Then it should trigger the validation rule

        • Brian Day
        • March 7th, 2012

        Hi,
        I am trying to use your approach to send parent element’s datacontext as parameter to ValidationRule.
        The problem is that, as pointed out by Shady, the initial value is null (i.e. the PropertyChanged event is not fired initially).
        Could you help on how to correct this?

  1. February 5th, 2013

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: