0
votes

I'm not very clear on how validation rules in wpf works.It seems that I'm missing a lot. I was following a tutorial on having a "Textbox is required" validation to a TextBox.

The tutorial has done it on xaml. However, I have dynamic textboxes created in the back code(C#).

in Xaml I added the following Resources

<UserControl.Resources>
    <ControlTemplate x:Key="validationTemplate">
        <DockPanel>
            <TextBlock Foreground="Red" FontSize="25" Text="*" DockPanel.Dock="Right"></TextBlock>
            <AdornedElementPlaceholder/>
        </DockPanel>
    </ControlTemplate>

    <Style x:Key="InputControlErrors" TargetType="{x:Type TextBox}">
        <Style.Triggers>
            <Trigger Property="Validation.HasError" Value="true">
                <Setter Property="ToolTip"    
          Value="{Binding RelativeSource={x:Static RelativeSource.Self},    
                          Path=(Validation.Errors)[0].ErrorContent}"/>
            </Trigger>
        </Style.Triggers>
    </Style>
</UserControl.Resources>

Also, I added the validation class

 public class RequiredFiedValidationRule : ValidationRule {
 public RequiredFiedValidationRule() {

  }
  public override ValidationResult Validate(object value, CultureInfo cultureInfo) {
      if (value.ToString().Length > 0) {
          return new ValidationResult(true, null);
      }
      else {
          return new ValidationResult(false, "Required Field Validation");
      }
  }
}

In this part of my code I generate the Textboxes in a for loop. The tutorial has all the binding done in Xaml, and I tried to do the same thing in my code during the creation of a each TextBox.The code runes with no errors but no results on the validation part (it still accepts null values). Note: this is just a part of the code inside the for loop, I deleted what is not important.

 foreach (Department department in Departments) { 
            TextBox textBox = new TextBox();
            textBox.Name = "Department" + department.Id.ToString();
            textBox.Width = 70;
            textBox.MaxWidth = 70;
            textBox.HorizontalAlignment = HorizontalAlignment.Center;
            textBox.VerticalAlignment = VerticalAlignment.Center;
            Grid.SetColumn(textBox, 1);
            Grid.SetRow(textBox, row);

            //me trying to attache the validation rule with no luck :(

            Validation.SetErrorTemplate(textBox, this.FindResource("validationTemplate") as ControlTemplate);
            textBox.Style= this.FindResource("InputControlErrors") as Style;
            Binding binding = new Binding();
            binding.Source = this;
            binding.Path = new PropertyPath(textBox.Name);
            binding.Mode = BindingMode.TwoWay;
            binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            RequiredFiedValidationRule textBoxRequiredRule = new RequiredFiedValidationRule();
            binding.ValidationRules.Add(textBoxRequiredRule);
            BindingOperations.SetBinding(textBox, TextBox.TextProperty, binding);
            NCRGrid.Children.Add(textBox);
        }
    }

to be honest I'm not sure what I'm doing in the validation part I was just trying to make it work.

1
c-sharpcorner.com/blogs/wpf-required-field-validation1 this is the tutorial I was trying to mimic - Muhannad

1 Answers

1
votes

You need to bind the Text property of the TextBox to a source property for the validation to work.

The Department class should have a string property, let's call it Name, that the TextBox binds to:

Binding binding = new Binding();
binding.Source = department; // <--
binding.Path = new PropertyPath("Name"); //<-- "Name" refers to a property of the Department class
binding.Mode = BindingMode.TwoWay;
binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;