Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to bind values from xaml to validation rule?

Tags:

c#

.net

wpf

xaml

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.

like image 974
Jasmeet Avatar asked Oct 02 '17 05:10

Jasmeet


People also ask

What is validation WPF?

A common requirement for any user interface application that accepts user input is to validate the entered information to ensure that it has the expected format and type for the back-end to be able to accept and persist it.


1 Answers

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

like image 120
mm8 Avatar answered Sep 18 '22 20:09

mm8