Jasmeetsingh Bansal Jasmeetsingh Bansal - 3 years ago 155
C# Question

How to bind values from xaml to validation rule?

I am a newbie at .net development so please help me out here.

I am trying to pass a value from c# class to a validation rule by means of xaml data binding.

C# class:

public class NumericDoubleUpDownValueContainerVM : SimpleValueContainerVM<string>
{
public NumericDoubleUpDownValueContainerVM(double value, double minValue, double maxValue, int decimalPlace) : base(value.ToString())
{
this.MinimumValue = minValue;
this.MaximumValue = maxValue;
this.DecimalPlaces = decimalPlace;
}

public double MinimumValue { get; set; }

public double MaximumValue { get; set; }

public int DecimalPlaces { get; set; }

public override void UpdatePropertyValue(object value, string propertyName = "")
{
this.Value = Convert.ToString(value);
}
}


Here
SimpleValueContainerVM<T>
is a generic class that is used to get and set the values from corresponding UI elements.

Xaml code :

<DataTemplate DataType="{x:Type VM:NumericDoubleUpDownValueContainerVM}" >
<Grid x:Name="Maingrid" >
<WPFStyles.CustomControls:NumericUpDown Minimum="{Binding MinimumValue}" Maximum="{Binding MaximumValue}" x:Name="Value" Width="{Binding ActualWidth, ElementName=Maingrid}"
VerticalAlignment="Center" YIncrementValue="0.1" DecimalPlaces ="{Binding DecimalPlaces}"
ToolTip="{Binding ValueToolTip, Converter={x:Static utils:StringToLocalizedStringConverter.Instance}, ConverterParameter=ToolTip}">
<Binding Path="Value" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay" ValidatesOnDataErrors="True">
<Binding.ValidationRules>
<validationRule:DoubleValidationRule/>
<validationRule:ValueWithinLimitsRule ValidatesOnTargetUpdated="True" ValidationStep="RawProposedValue" />
</Binding.ValidationRules>
</Binding>
</WPFStyles.CustomControls:NumericUpDown>
</Grid>
</DataTemplate>


Here ValueWithinLimits Rule is the one am working with :

The validation Rule is given as :

public class ValueWithinLimitsRule : ValidationRule
{
public double MaxVal { get; set; }

public double MinVal { get; set; }

public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
if (value != null)
{
if (Convert.ToDouble(value.ToString()) > this.MaxVal || Convert.ToDouble(value.ToString()) < this.MinVal)
{
return new ValidationResult(false, null);
}
else
{
return new ValidationResult(true, null);
}
}

return new ValidationResult(false, null);
}
}


I tried something like

<validationRule:ValueWithinLimitsRule ValidatesOnTargetUpdated="True" ValidationStep="RawProposedValue" MinVal="0" MaxVal="100"/>


and that just works fine.

Now i want to use the properties of
NumericDoubleUpDownValueContainerVM


MinimumValue and MaximumValue


in place of 0 and 100.

I have tried googling and getting to know dependency properties and objects however cant get a hold of it.

I would really appreciate any help.

mm8 mm8
Answer Source

You could create a wrapper class that derives from DependencyObject and exposes a dependency property. Then you add a CLR property to the ValidationRule class that returns an instance of this wrapper type.

public class AgeValidationRule : ValidationRule
{
    public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
    {

        string text = value.ToString();
        int age;
        int.TryParse(text, out age);
        if (age < 10 || age > this.Wrapper.MaxAge)
            return new ValidationResult(false, "Invalid age.");

        return ValidationResult.ValidResult;
    }

    public Wrapper Wrapper { get; set; }
}

public class Wrapper : DependencyObject
{
    public static readonly DependencyProperty MaxAgeProperty =
         DependencyProperty.Register("MaxAge", typeof(int),
         typeof(Wrapper), new FrameworkPropertyMetadata(int.MaxValue));

    public int MaxAge
    {
        get { return (int)GetValue(MaxAgeProperty); }
        set { SetValue(MaxAgeProperty, value); }
    }
}

XAML:

<TextBox xmlns:local="clr-namespace:WpfApplication1">
    <TextBox.Text>
        <Binding Path="Age" UpdateSourceTrigger="PropertyChanged">
            <Binding.ValidationRules>
                <local:AgeValidationRule>
                    <local:AgeValidationRule.Wrapper>
                        <local:Wrapper MaxAge="{Binding MaxAge}"/>
                    </local:AgeValidationRule.Wrapper>
                </local:AgeValidationRule>
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

Please refer to the following article for more information and a full example.

WPF: Passing a Data Bound Value To a Validation Rule: https://social.technet.microsoft.com/wiki/contents/articles/31422.wpf-passing-a-data-bound-value-to-a-validation-rule.aspx

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download