I have a tricky problem with a WPF data grid and validation error tooltips not updating when validation messages change. This is with .Net 4 code, so I can't use INotifyDataErrorInfo.
I have an ObservableCollection bound to a datagrid. The object type in the collection implements IDataErrorInfo so that we can support validation and highlight fields that have invalid values. This works fine in most cases. However, there are issues with the message that is displayed in the tooltip in the following scenario:
- Field A has two rules Rule 1 and Rule S (a shared rule)
- Field B has one rule Rule S (the shared rule)
- Rule S is a shared rule than references both Field A and Field B
If Rule 1 and Rule S are both invalid, we get the following validation tooltips shown for each field, which is the behaviour we want:
Field A < "Rule 1 is invalid. Rule S is invalid" Field B < "Rule S is invalid"If we now edit field B to make Rule S valid. We want both the tooltip messages to update as follows:
Field A < "Rule 1 is invalid." Field B < (valid - no tooltip)
Note, the validation state of field A has not changed (Validation.HasError does not change value), only the message bound to the tooltip.
What we actually see is:
Field A < "Rule 1 is invalid. Rule S is invalid"
Field B < (valid - no tooltip)
NB the underlying ValidationError data on the class instance is correct at this point.
It appears that the UI will not update the tooltip text for field A unless we force it to requery the state and call IDataErrorInfo.this[string columnName] again. The only way I have found to force this to happen is to manually raise the property changed event for field A. However, I don't want to have to do this since the value of field A hasn't actually changed, only the bound error messages. While this solution works the extra and unnecessary property changed events play havok with the performance with lots of data.
What can I do to force IDataErrorInfo.this[string columnName] to be called for field B without having to go as far as raising a property changed event?
NB here's the error data template we use to display the validation message.
<!-- ERROR HANDLING Data Template -->
<Style x:Key="controlBaseStyle"
TargetType="{x:Type Control}">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<Border BorderBrush="Red"
BorderThickness="2"
Visibility="{Binding ElementName=placeholder, Path=AdornedElement.IsVisible, Converter={StaticResource BooleanToVisibilityConverter}}">
<AdornedElementPlaceholder x:Name="placeholder"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ToolTipService.ShowOnDisabled" Value="true"/>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors).CurrentItem, Converter={StaticResource ErrorContentConverter}}"/>
</Trigger>
<!--We don't want to see the validation if the control is disabled. This doesn't affect it if the control is read only. -->
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<AdornedElementPlaceholder x:Name="placeholder"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>