Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF How to use a validation rule in a textbox without creating an extra property to bind to in dialogbox?

so I have one example that is working here:

     <TextBox.Style>
          <Style TargetType="{x:Type TextBox}">
            <Style.Triggers>
              <Trigger Property="Validation.HasError" Value="true">
                <Setter Property="ToolTip"
                          Value="{Binding RelativeSource={RelativeSource Self}, 
                        Path=(Validation.Errors), Converter={StaticResource ValidationConverter}}"
                        />
              </Trigger>
              <Trigger Property="Validation.HasError" Value="false">
                <Setter Property="ToolTip"
                          Value="GraphPenWidth" />
                <Setter Property="Background" 
                    Value="Blue"
                    />
              </Trigger>
            </Style.Triggers>
          </Style>
        </TextBox.Style>
        <TextBox.Text>
          <Binding Path="GraphPenWidth" UpdateSourceTrigger="PropertyChanged"  Mode="TwoWay">
            <Binding.ValidationRules>
              <DaedalusValidationRules:IntegerValidationRule />
            </Binding.ValidationRules>
          </Binding>
        </TextBox.Text>

However, is there any way to use a validation rule without binding to a datacontext?

I am trying to make a generic dialogbox that I can pass various validation rules to. However, I found after a while that even when I create the validation rule in xaml it wasn't working correctly. I had read that I could just bind the TextBox's Text Property to itself, but this did not work.

However, when I put a breakpoint in the ValidationRule it seems to be getting called at the correct point when I insert data. In addition the style appears to be working because the background is blue. That leads me to believe that Validation.HasError is never becoming true or is becoming true and changing back so fast that I can't see the change.

The validation rule gets called after every letter I type, yet the textbox doesn't update to show haserror = true. why is this?

Am I just not allowed to bind a property to itself? is there any other way I can use a validation rule without having a binding or do I just always have to create an extra property to bind to? The shortest fix is just to create an extra text property and bind it pointlessly, but I had hoped that wasn't necessary.

 <TextBox    
    Margin="3"
    Height="25"
    VerticalAlignment="Center"
    VerticalContentAlignment="Center"
    HorizontalContentAlignment="Left"
    Grid.Column="1"
    x:Name="MainTextBox"
    >
    <TextBox.Text>
      <Binding RelativeSource="{RelativeSource Self}" Path="Text" UpdateSourceTrigger="PropertyChanged">
        <Binding.ValidationRules>
          <rules:IntegerValidationRule />
        </Binding.ValidationRules>
      </Binding>
    </TextBox.Text>

    <TextBox.Style>
      <Style 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), Converter={StaticResource ValidationConverter}}"
                    />
            <Setter Property="Background" 
                    Value="Red"
                    />
          </Trigger>
          <Trigger Property="Validation.HasError" Value="false">
            <Setter Property="ToolTip"
                          Value="Default Signal Height Percentage" />
            <Setter Property="Background" 
                    Value="Blue"
                    />
          </Trigger>
        </Style.Triggers>
      </Style>
    </TextBox.Style>
  </TextBox>

So I actually managed to get the validation working in xaml by just making a property to bind against called Text on the GenericDialogBox and then binding that Text property to the Text Property of the Textbox. However, I can't seem to get the same code to work in the code behind.

  <TextBox.Text>
      <Binding Path="Text" UpdateSourceTrigger="PropertyChanged">
        <Binding.ValidationRules>
          <rules:IntegerValidationRule />
        </Binding.ValidationRules>
      </Binding>
    </TextBox.Text>

but when i try this in the code behind, it doesn't work.

  Binding myBinding = new Binding();
  myBinding.Source = this;
  myBinding.Path = new PropertyPath("Text");
  myBinding.NotifyOnValidationError = true;
  myBinding.NotifyOnSourceUpdated = true;

  myBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;

  myBinding.ValidationRules.Add(rule);
  MainTextBox.SetBinding(TextBlock.TextProperty, myBinding);

what am I missing?

like image 252
James Joshua Street Avatar asked Apr 01 '14 02:04

James Joshua Street


1 Answers

Try set for your Binding NotifyOnValidationError to True, by default it is False:

Gets or sets a value that indicates whether the BindingValidationError event is raised on validation errors.

Example:

<Binding NotifyOnValidationError="True" UpdateSourceTrigger="PropertyChanged" ... />

Also you can see the ValidatesOnDataErrors property, he is used when your ViewModel implement the IDataErrorInfo interface.

like image 50
Anatoliy Nikolaev Avatar answered Oct 06 '22 00:10

Anatoliy Nikolaev