私はDataGridに複数のComboBox列があるとします。値は、ViewModelのIDataErrorInfoインターフェイスを使用して検証されます。適切なセルにカーソルを移動すると、ツールチップに検証エラーが表示されます。WPF:検証ツールチップをDataGridComboBoxColumnに表示
この動作を達成するための通常のアプローチは、次のような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 行とエラーを取得するには、ハードコーディングされたインデックスを使用しています。これは私にとって非常に誤りのようです。とにかく、行内に唯一の検証エラーが存在する限り、動作するはずです。しかし、同じ行に2つ以上の検証エラーが発生するとすぐに、それはもはや機能しません。すべてのツールチップは、(理由は、ハードコードされたインデックスの)最初の検証エラーを示しています。私はエラーを取得する代わりにDataGridRowのDataGridCellを使用するため
だから、(下のバインディングで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を返すことを示します。
結合ツールチップの周りにトリガを削除する場合は、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>
は、誰かがこの問題の解決策を持っていますか?
私は現在TextBlockComboBoxをTextBlockに置き換えるためにDataGridComboBoxColum.GenerateElement()をオーバーライドしようとしています。これは基本的にあなたと同じアプローチです。 SelectedValuePathとDisplayMemberPathで作業しているので、あまり簡単ではありません。 – fss
カスタムクラスを作成し、ComboBoxをTextBlockに置き換えるためにGenerateElement()メソッドをオーバーライドしようとしているのはなぜですか?これは意味をなさない。私の答えで示唆したようにDataGridTemplateColumnを使用してください。 – mm8
多くのカスタマイズを含む従来のコード;-) – fss