У меня есть DataGrid, и я проверяю пользовательский ввод для каждой ячейки, используя IDataErrorInfo
. Соответствующее сообщение об ошибке отображается для каждой ячейки, когда пользователь вводит неверные данные.
Как собрать и отобразить все сообщения об ошибках ячеек строки при наведении курсора ValidationErrorTemplate (controltemplate) в левой части строки сетки?
<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>
Обновление 2019-01-25:
Мой стиль, определяющий ошибочную ячейку:
<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>
Обновление 2019-02-18:
Вот так выглядит DataGridRow после ввода недопустимого символа:
Вот так выглядит DataGridRow после удаления всех недопустимых символов:
-> Красная граница все еще находится вокруг строки, а предупреждающий знак с левой стороны строки все еще виден.
Я тоже это попробовал:
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));
}
... хотя я все равно использую OnPropertyChange
в каждом сеттере этого модельного класса. Список ошибок пуст, но граница и символ предупреждения остаются.
Обновление 2019-02-19:
Моя реализация интерфейса INotfiyPropertyChanged:
#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