I have a DataGrid and I validate the user input for each cell using IDataErrorInfo. An appropriate error message is displayed for each cell when the user inputs invalid data.
How can I collect and display all row's cell error messages when I hover the ValidationErrorTemplate (controltemplate) on the left hand side of the grid's row?
<Style TargetType="{x:Type DataGridRow}">
<Setter Property="FontSize" Value="16"/>
<Setter Property="FontFamily" Value="ArialMT"/>
<Setter Property="Height" Value="24"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="ValidationErrorTemplate">
<Setter.Value>
<ControlTemplate>
<Grid>
<Ellipse Width="12" Height="12" Fill="Red" Stroke="Black" StrokeThickness="0.5"/>
<TextBlock FontWeight="Bold" Padding="4,0,0,0" Margin="0" VerticalAlignment="Top" Foreground="White" Text="!" />
<!--<ToolTip {Binding RelativeSource={RelativeSourceSelf}, Path=(Validation.Errors)[0].ErrorContent}"/>-->
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<!--<DataTrigger Binding="{Binding Path=(Validation.HasError), RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGridRow}}" Value="true" >-->
<!--<DataTrigger Binding="{Binding Path=(Validation.HasError), RelativeSource={RelativeSource Self}}" Value="true" >-->
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="IsEnabled" Value="True" />
</Trigger>
<Trigger Property="Validation.HasError" Value="false">
<!--<DataTrigger Binding="{Binding Path=(Validation.HasError), RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGridRow}}" Value="false" >-->
<!--<DataTrigger Binding="{Binding Path=(Validation.HasError), RelativeSource={RelativeSource Self}}" Value="false" >-->
<Setter Property="ToolTip" Value="{x:Null}"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="IsEnabled" Value="True" />
</Trigger>
</Style.Triggers>
</Style>
Update 2019-01-25: My style defining an erroneous cell:
<Style x:Key="textBlockErrStyle" TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=(Validation.HasError), RelativeSource={RelativeSource Self}}" Value="false" >
<Setter Property="ToolTip" Value="{x:Null}"/>
</DataTrigger>
<DataTrigger Binding="{Binding (Validation.HasError), RelativeSource={RelativeSource Self}}" Value="true" >
<Setter Property="Background" Value="Red" />
<Setter Property="Foreground" Value="White" />
<Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
<!--<Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=RawTag.ErrorList, Converter={StaticResource conv:StringToListConverter}}"/>-->
</DataTrigger>
</Style.Triggers>
</Style>
Update 2019-02-18:
This is how the DataGridRow looks like after an invalid character was entered:

This is how the DataGridRow looks like after all invalid characters were deleted:

--> The red border is still around the row and the alert sign on the left hand side of the row is still visible.
I tried this as well:
public void RemoveError(string propertyName, bool notify = true)
{
if (ErrorList.ContainsKey(propertyName))
{
ErrorList.Remove(propertyName);
HasErrors = ErrorList.Count > 0;
//NotifyErrorsChanged(propertyName);
OnPropertyChanged(propertyName);
OnPropertyChanged("GetAllErrors");
}
if (notify) ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
}
...although I use OnPropertyChange anyway in each setter of th model class. The error list is empty but the border and the alert symbol stay.
Update 2019-02-19:
My implementation of the INotfiyPropertyChanged interface:
#region INotifyPropertyChanged
/// <summary>
/// Handler to register for property changed event
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Method to invoke the property change event
/// </summary>
/// <param name="propertyName">The name of the changed property</param>
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
I display the tool tip like this:
Here is the entire template.
Looks like this:
Edit: Info added per comment
If you want to display a list of all errors you will need to implement
INotifyDataErrorInfointerface for your class. Then do something like this:Then in your RowStyle for the datagrid set the tooltip like this:
You should be able get a tooltip of all the errors by hovering any portion of the row.
EDIT 2: I added my own methods to remove errors.