Validation.HasError does not trigger again if new error comes in while already true
I use MVVM and my object implement IDataErrorInfo. When a property is set, I run custom validation methods and if the validation passes, I return String.empty, which sets Validation.HasError to false. If the validation fails, Validation.HasError is set to true. I have a style that I use for "required controls" (controls that will perform the validation) and set's the ToolTip of the control to whatever the error is like this:
<Style x:Key="RequiredControl" TargetType="{x:Type Control}" >
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip" Value="{Binding (Validation.Errors), Converter={StaticResource ErrorConverter}, RelativeSource={x:Static RelativeSource.Self}}"/>
</Trigger>
</Style.Triggers>
</Style>
And the ErrorConverter:
public class ZynErrorContentConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var errors = value as ReadOnlyObservableCollection<ValidationError>;
if (errors == null) return "";
return errors.Count > 0 ? errors[0].ErrorContent : "";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
The problem is this: The user enters something invalid...and the Validation.HasError is set to true. The tooltip updates as it is supposed to. If the user attempts to correct the error, but enters a value that causes a different type of invalidation, the tooltip should show the new error stri开发者_Python百科ng, but this doesn't happen. The error shows as the same error from the first error. I know why this happens (I think)...Because the Trigger is not triggered because the Validation.HasError never changes from True -> False -> True.
Does anyone have any experience with this or some advice as to how to force the trigger?
This appears to be the answer: IDataErrorInfo With Multiple Error Messages for a Property
Basically, you bind to the current item and use a ContentPresenter to display the error. It worked for my code.
I believe I have figured this out. The culprit is the use of the converter. I was experiencing the same issue and the problem code snippet was:
<Setter Property="ToolTip"
Value="{Binding RelativeSource={x:Static RelativeSource.Self},
Path=(Validation.Errors),
Converter={StaticResource validationErrorsToStringConverter }}"/>
I change the snippet to :
<Setter Property="ToolTip"
Value="{Binding RelativeSource={x:Static RelativeSource.Self},
Path=(Validation.Errors)[0].ErrorContent}"/>
and the issue was resolved.
Conclusion - Do not use a Converter.
I had a similar problem and what solved it was to remove the converter as Allan mentioned in his answer.
But instead of getting the ErrorContent
by index such as, Path=(Validation.Errors)[0].ErrorContent
, I used the current record pointer to get the current item.
Here is what it looks like in code:
<Setter Property="ToolTip"
Value="{Binding RelativeSource={x:Static RelativeSource.Self},
Path=(Validation.Errors)/ErrorContent}" />
More info can be found here: https://learn.microsoft.com/en-us/dotnet/api/system.windows.data.relativesource.self?view=netframework-4.8
精彩评论