Search code examples
c#.netwpfvalidationrulesvalidationrule

Does System.Windows.Controls.ValidationRule only support Value Types for properties


I am using following System.Windows.ValidationRule.

public class XXXValidationRule : ValidationRule
{
    public object FooObject { get; set;}
    public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
    {
        Bar barObject = this.FooObject.BarObject;
    }
}

My XAML shows like this.

<ui:Windows.Resources>
    <ResourceDictionary>
       <viewModel:XXXValidationRule x:key="xxxValidationRule"/>
    </ResourceDictionary>
</ui:Windows.Resources>
...
<TextBox.Text>
    <Binding Path="..." UpdateSourceTrigger="PropertyChanged">
        <Binding.ValidationRules>                   
            <viewModel:XXXValidationRule/>
        </Binding.ValidationRules>
    </Binding>
</TextBox.Text>

So far so good. Now in the Code Behind of my XAML Dialog I initialize the ValidationRule as follow.

public partial class XamlDialog : System.Windows.Window
{
    private System.Windows.Controls.ValidationRule xxxValidationRule;

    public XamlDialog()
    {
        InitializeComponent();
        InitializeResources();
    }

    public void InitializeResources()
    {
       this.xxxValidationRule = (ValidationRule)this.Resources["xxxValidationRule"];
       this.xxxValidationRule.FooObject= new FooObject();
    }
    ...
 }

The point is, when XXXValidationRule.Validate is triggered the FooObject Property is always null.

If I work with the value type int for the Property FooObject, same effect.

If I work still with the value type int and set the Property explicitly in XAML like follow, I receive the correct value (99) within the Validation Rule.

<Binding.ValidationRules>
    <viewModel:XXXValidationRule FooObject="99"/>
</Binding.ValidationRules>
...

First, does ValidationRule only supports value types or is there a way to work with reference types as described above? Second, do we have to set such Properties explicitly in XAML or is there a way to set it in Code Behind?

Thanks for help :-)


Solution

  • Just found the solution. Thanks to the comment of dkozl and this stackoverflow answer https://stackoverflow.com/a/3173461/3835909

    If we define the Validation Rule such as

    <Binding.ValidationRules>
        <viewModel:XXXValidationRule FooObject="99"/>
    </Binding.ValidationRules>
    ...
    

    means that the Binding Binding.ValidationRules will create always new instance of XXXValidationRule. To resolve that use StaticResource as follow.

    <Binding.ValidationRules>
        <StaticResource ResourceKey="xxxValidationRule"/>
    </Binding.ValidationRules>
    ...