我有一个DataGrid,里面有几个ComboBox列。使用ViewModel中的IDataErrorInfo接口验证这些值。当鼠标悬停在适当的单元格上时,工具提示应显示验证错误。
实现此行为的常规方法是使用如下的ElementStyle:
<DataGridComboBoxColumn ...>
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="ComboBox">
...
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
</DataGridComboBoxColumn.ElementStyle>
</DataGridComboBoxColumn>
这适用于DataGridTextColumns,但不适用于DataGridComboBoxColumns (未显示工具提示)。如果相同的代码用于编辑 ElementStyle,一切正常。但仅当单元格处于编辑模式时(正如预期的那样,因为EditingElementStyle仅用于编辑模式)。
WWW中发现的这个问题的解决方案建议使用像这样的CellStyle:
<DataGridComboBoxColumn ...>
<DataGridComboBoxColumn.CellStyle>
<Style TargetType="DataGridCell">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=(Validation.HasError), RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridRow}}}"
Value="True">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGridRow}}, Path=(Validation.Errors)[0].ErrorContent}" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridComboBoxColumn.CellStyle>
</DataGridComboBoxColumn>
此方法使用DataGrid 行和硬编码索引来获取错误。这对我来说似乎非常容易出错。无论如何,只要行中只有一个验证错误,它就应该工作。但是,只要同一行中存在两个或更多验证错误,它就不再起作用了。每个工具提示都显示第一个验证错误(因为硬编码索引):
因此,我很自然地使用DataGridCell而不是DataGridRow来获取错误(请参阅下面绑定中的RelativeSource):
<DataGridComboBoxColumn ...>
<DataGridComboBoxColumn.CellStyle>
<Style TargetType="DataGridCell">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=(Validation.HasError), RelativeSource={RelativeSource Self}}"
Value="True">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridComboBoxColumn.CellStyle>
</DataGridComboBoxColumn>
但是使用此样式,不会显示工具提示。输出窗口中没有错误或警告。将PresentationTraceSources.TraceLevel = High添加到触发器绑定显示,HasError属性返回false。
删除Tooltip绑定周围的触发器时,Validation.Errors似乎不包含任何值:
System.Windows.Data Warning: 56 : Created BindingExpression (hash=13069983) for Binding (hash=50848483)
System.Windows.Data Warning: 58 : Path: '(0)[0].ErrorContent'
System.Windows.Data Warning: 60 : BindingExpression (hash=13069983): Default mode resolved to OneWay
System.Windows.Data Warning: 61 : BindingExpression (hash=13069983): Default update trigger resolved to PropertyChanged
System.Windows.Data Warning: 62 : BindingExpression (hash=13069983): Attach to System.Windows.Controls.DataGridCell.ToolTip (hash=21168757)
System.Windows.Data Warning: 67 : BindingExpression (hash=13069983): Resolving source
System.Windows.Data Warning: 70 : BindingExpression (hash=13069983): Found data context element: <null> (OK)
System.Windows.Data Warning: 72 : RelativeSource.Self found DataGridCell (hash=21168757)
System.Windows.Data Warning: 78 : BindingExpression (hash=13069983): Activate with root item DataGridCell (hash=21168757)
System.Windows.Data Warning: 108 : BindingExpression (hash=13069983): At level 0 - for DataGridCell.(Validation.Errors) found accessor DependencyProperty(Errors)
System.Windows.Data Warning: 104 : BindingExpression (hash=13069983): Replace item at level 0 with DataGridCell (hash=21168757), using accessor DependencyProperty(Errors)
System.Windows.Data Warning: 101 : BindingExpression (hash=13069983): GetValue at level 0 from DataGridCell (hash=21168757) using DependencyProperty(Errors): ReadOnlyObservableCollection`1 (hash=51278326 Count=0)
System.Windows.Data Warning: 109 : BindingExpression (hash=13069983): At level 1 - for ReadOnlyObservableCollection`1[] found accessor RuntimePropertyInfo(Item)
System.Windows.Data Warning: 104 : BindingExpression (hash=13069983): Replace item at level 1 with ReadOnlyObservableCollection`1 (hash=51278326 Count=0), using accessor RuntimePropertyInfo(Item)
System.Windows.Data Warning: 101 : BindingExpression (hash=13069983): GetValue at level 1 from ReadOnlyObservableCollection`1 (hash=51278326 Count=0) using RuntimePropertyInfo(Item): {IListIndexOutOfRange}
System.Windows.Data Error: 17 : Cannot get 'Item[]' value (type 'ValidationError') from '(Validation.Errors)' (type 'ReadOnlyObservableCollection`1'). BindingExpression:Path=(0)[0].ErrorContent; DataItem='DataGridCell' (Name=''); target element is 'DataGridCell' (Name=''); target property is 'ToolTip' (type 'Object') ArgumentOutOfRangeException:'System.ArgumentOutOfRangeException: Das angegebene Argument liegt außerhalb des gültigen Wertebereichs.
Parametername: index'
System.Windows.Data Warning: 103 : BindingExpression (hash=13069983): Replace item at level 2 with {NullDataItem}
System.Windows.Data Warning: 80 : BindingExpression (hash=13069983): TransferValue - got raw value {DependencyProperty.UnsetValue}
System.Windows.Data Warning: 88 : BindingExpression (hash=13069983): TransferValue - using fallback/default value <null>
System.Windows.Data Warning: 89 : BindingExpression (hash=13069983): TransferValue - using final value <null>
有人有解决这个问题的方法吗?
答案 0 :(得分:2)
有人有解决这个问题的方法吗?
为什么不简单地用DataGridComboBoxColumn
替换DataGridTemplateColumn
并使用CellTemplate中的TextBlock和CellEditingTemplate中的ComboBox?
更灵活,结果完全相同。最重要的是它实际上解决了你的问题:
<DataGridTemplateColumn Header="...">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name, ValidatesOnDataErrors=True}">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip" Value="{Binding (Validation.Errors)[0].ErrorContent, RelativeSource={RelativeSource Self}}"/>
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding SomeItems, RelativeSource={RelativeSource AncestorType=Window}}"
SelectedItem="{Binding Name, ValidatesOnDataErrors=True}">
<ComboBox.Style>
<Style TargetType="ComboBox">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip" Value="{Binding (Validation.Errors)[0].ErrorContent, RelativeSource={RelativeSource Self}}"/>
</Trigger>
</Style.Triggers>
</Style>
</ComboBox.Style>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
当DataGridComboBoxColumn处于只读模式时,没有&#34; real&#34; ComboBox显示。