Add ValidationRule in XAML from code behind

4.4k views Asked by At

I am trying to add a ValidationRule to XAML from code behind and and need to have this:

<TextBox.Text>
   <Binding Path="Model.txt1.Value" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors="True">
      <Binding.ValidationRules>
         <localVal:RequiredValidate />
      </Binding.ValidationRules>
   </Binding>
</TextBox.Text>

I have tried this so far:

FrameworkElement SelectedObject = fe_dragged_control;
DependencyProperty property =                           
    ControlBindingExtensions.GetDependencyPropertyFromName("Text", SelectedObject.GetType());
Binding binding = new Binding("Model." + SelectedObject.Name + ".Value");
binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
binding.ValidatesOnDataErrors = true;
RequiredValidate role = new RequiredValidate();
binding.ValidationRules.Add(role);
SelectedObject.SetBinding(property, binding);

I found this on google, but I am getting the following result (removed irrelevant properties for readability:

<TextBox Text="{Binding ValidatesOnDataErrors=True, 
                Path=Model.txt0.Value, 
                UpdateSourceTrigger=PropertyChanged}" >

How do I get to have the the result I need (the 1st code)? Thanks

1

There are 1 answers

5
Chui Tey On

You should check your viewmodel. Your sample worked with the following test case.

<TextBox x:Name="Txt0">

Validation

using System.Globalization;
using System.Windows.Controls;

namespace WpfApplication2
{
    public class RequiredValidate : ValidationRule
    {
        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
        {
            return value != null ? ValidationResult.ValidResult : new ValidationResult(false, "Value required");
        }
    }
}

Code behind

    private void InitializeValidation()
    {

        FrameworkElement SelectedObject = Txt0;
        DependencyProperty property =
            GetDependencyPropertyByName(SelectedObject, "TextProperty");
        Binding binding = new Binding("Model.Txt0");
        binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
        binding.ValidatesOnDataErrors = true;
        RequiredValidate role = new RequiredValidate();
        binding.ValidationRules.Add(role);
        SelectedObject.SetBinding(property, binding);
    }

    public static DependencyProperty GetDependencyPropertyByName(DependencyObject dependencyObject, string dpName)
    {
        return GetDependencyPropertyByName(dependencyObject.GetType(), dpName);
    }

    public static DependencyProperty GetDependencyPropertyByName(Type dependencyObjectType, string dpName)
    {
        DependencyProperty dp = null;

        var fieldInfo = dependencyObjectType.GetField(dpName, BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);
        if (fieldInfo != null)
        {
            dp = fieldInfo.GetValue(null) as DependencyProperty;
        }

        return dp;
    }

and ViewModels

public class MainWindowViewModel
{
    public MainWindowViewModel()
    {
        Model = new Model();
    }

    public Model Model { get; set; }
}

public class Model
{
    public Model()
    {
        Txt0 = 42;
        Txt1 = 99;
    }

    public int? Txt0 { get; set; }
    public int? Txt1 { get; set; }
}