0

I created validation in WPF with the help of a ValidationRule :

public class EmptyValidationRule : ValidationRule
{
    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        if (!string.IsNullOrEmpty(value.ToString()))
        {
            return new ValidationResult(true, null);
        }

        return new ValidationResult(false, "Dit veld is verplicht.");
    }
}

And I use it like this :

<StackPanel Grid.Column="1"
            Grid.Row="0"
            Margin="10 0 0 20">
    <TextBox Width="200"
             Height="30"
             HorizontalAlignment="Left"
             VerticalContentAlignment="Center">
        <TextBox.Text>
            <Binding Path="Product.ProductName" Mode="TwoWay" UpdateSourceTrigger="LostFocus">
                <Binding.ValidationRules>
                    <validators:EmptyValidationRule ValidationStep="RawProposedValue" />
                </Binding.ValidationRules>
            </Binding>
        </TextBox.Text>
        <Validation.ErrorTemplate>
            <ControlTemplate>
                 <StackPanel>
                     <!-- Placeholder for the TextBox itself -->
                     <AdornedElementPlaceholder x:Name="textBox"/>
                     <TextBlock Text="{Binding [0].ErrorContent}" Foreground="Red"/>
                 </StackPanel>
            </ControlTemplate>
        </Validation.ErrorTemplate>
    </TextBox>
</StackPanel>

It works but not as expected. For example if the windows is loaded and you use Tab to jump to the next field the message is not shown. But when I type in the field and then remove it it shows the message.

Start up :

enter image description here

If I click in the TextBox and press Tab no message is shown :

enter image description here

If I click again in the first TextBox and type something and then remove it again and pres Tab, the message is shown :

enter image description here

How can I fix this? Or how can I show the message when I click on the button?

user7849697
  • 503
  • 1
  • 8
  • 19
  • I don't know specifically, but have you tried using IsEmptyOrWhitespace instead of IsNullOrEmpty? – crazywill32 Apr 30 '21 at 15:10
  • You could also try looking at if it works correctly for a update trigger of PropertyChanged instead of lost focus. If it works then, it is because the focus is not being set on that box by default. You could try setting the default focus. This post might help set the focus https://stackoverflow.com/questions/817610/wpf-and-initial-focus. – crazywill32 Apr 30 '21 at 15:17
  • Validationrules are on bindings and apply as the data transfers. No entry. No transfer. No validation. I would usually validate the entire viewmodel to check for empty properties and use dataannotations to drive this. Having said that, magnus' suggestion might work but i think you'll see the message immediately if it does. – Andy Apr 30 '21 at 16:11

1 Answers1

1

Set the ValidatesOnTargetUpdated property of the ValidationRule to true:

 <validators:EmptyValidationRule ValidatesOnTargetUpdated="True" ValidationStep="RawProposedValue" />

Or update the source of the binding explicitly in your button click event handler or another one, like for example LostFocus:

textBox.GetBindingExpression(TextBox.TextProperty).UpdateSource();

Don't forget to check if value is null before you call ToString() on it in your validation rule:

if (!string.IsNullOrEmpty(value?.ToString()))
mm8
  • 163,881
  • 10
  • 57
  • 88