0

Let's presume there is a rule that the user can't enter both "X" for property Name AND "1" for Age, I know it's weird rule, but it will help descripe my problem. So in the indexer of INotifyDataErrorInfo in the model class, I added the rule:

switch(propertyName)
{
    bool hasError = false;

    case nameof(Name):
           if (Name == "X" && Age == 1)
              {
                 AddError(nameof(Name), "BAD input");
                 hasError = true;
              }
          if (!hasError)
              ClearErrors(nameof(Name));

     break;
    case nameof(Age):
          if (Name == "X" && Age == 1)
             {
                AddError(nameof(Age), "BAD input");
                hasError = true;
             }
          if (!hasError)
             ClearErrors(nameof(Age));
    break;
}

AddError just adds the error to the errors collection returned by GetErrors method.

Here's the XAML for the inputs:

<Label Grid.Row="2">Name</Label>
            <TextBox Grid.Column="1" Grid.Row="2" Name="txtName" Text="{Binding Path=Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnExceptions=True, ValidatesOnDataErrors=True}"/>
<Label Grid.Row="3">Age</Label>
            <TextBox Grid.Column="1" Grid.Row="3" Name="txtAge" Text="{Binding Path=Age, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnExceptions=True, ValidatesOnDataErrors=True}"/>

When I enter "X" for Name and "1" for Age, the error message is shown as expected in the error template:

<ListBox Grid.Row="8" Grid.ColumnSpan="2" ItemsSource="{Binding ElementName=mGrid, Path=(Validation.Errors)}">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <ListBox ItemsSource="{Binding Path=ErrorContent}"/>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>

When I suffix the input 1 with any letter to make it invalid input with the bound int field, the error in the template doesn't disappear, despite the input is not "X" AND "1". I set a breakpoint in the Age property, I found out that it doesn't get hit, so, I concluded that setting invalid input with the bound field data type doesn't call this field setter. But how can I Clear the error message from the template (the Clear method is inside the indexer that is called when propertyChanged fired => when the setter is called!), and how to show the correct message for entering invalid input instead.

I hope I could describe the problem clearly, hope for help, thanks!

mshwf
  • 7,009
  • 12
  • 59
  • 133
  • I suggest to allow only numeric input in age text box: https://stackoverflow.com/questions/1268552/how-do-i-get-a-textbox-to-only-accept-numeric-input-in-wpf – ASh Jul 02 '17 at 17:29
  • This isn't what I intended by asking the question, I don't want to solve the problem that way – mshwf Jul 02 '17 at 17:36
  • _"I concluded that setting invalid input with the bound field data type doesn't call this field setter"_ -- how could it? If the input isn't a valid `int` value, and your property has type `int`, what did you think WPF would do? Make up a random value and set your property to that? How would that be useful? If you want control over validation of text input, your view model property needs to be able to accept text input (i.e. type `string`). Otherwise, you can hook WPF's validation, to observe errors that occur before data reaches your view model. See marked duplicate for details on that. – Peter Duniho Jul 03 '17 at 00:19

0 Answers0