想象一下DataGrid的一個DataGrid,它的ItemsSource
設置爲ObservableCollection
。此集合爲DataGrid
中的每一行提供了查看模型。視圖模型反過來提供一行中顯示的數據和可能更改此數據的命令。此外,我在DataGrid
的RowValidationRules
屬性中添加了一條規則。如果我輸入無效數據,此驗證規則正常工作。驗證基礎數據更改時的行
但是,如果通過視圖模型提供的命令將無效數據更改爲有效數據,則只有當DataGrid
中的當前行失去焦點時,纔會再次觸發行驗證規則。因此,顯示的數據可能實際上是有效的,但DataGrid
仍顯示一個紅色感嘆號,表明它具有無效數據。在當前行失去焦點或我再次輸入有效數據之前,情況依然如此。
如何強制對當前行進行第二次驗證?我已經設置了ValidatesOnTargetUpdated="True"
但這並沒有解決問題。我也實現了INotifyPropertyChanged接口,但這也沒有解決問題。
解決方案
隨着用戶mm8指出,INotifyDataErrorInfo
是去的方法。我刪除了行驗證規則,並在我的視圖模型中公開了名爲HasErros
的屬性,該屬性代理了我的模型的HasErrors
屬性,該屬性依次執行INotifyDataErrorInfo
。接下來,我添加了一個自定義的RowValidationErrorTemplate
<DataGrid.RowValidationErrorTemplate>
<ControlTemplate>
<Grid>
<Ellipse Width="12" Height="12" Fill="Red"/>
<Label Content="!" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"
Foreground="White" FontSize="11"/>
</Grid>
</ControlTemplate>
</DataGrid.RowValidationErrorTemplate>
,並創建以下的自定義樣式DataGridRowHeader
<Style x:Key="MyDataGridRowHeaderStyle" TargetType="{x:Type DataGridRowHeader}">
<!-- ... -->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridRowHeader}">
<Border>
<Grid>
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
<Control SnapsToDevicePixels="True"
Template="{Binding ValidationErrorTemplate, RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}"
Visibility="{Binding Path=HasErrors, UpdateSourceTrigger=PropertyChanged, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}"/>
</Grid>
</Border>
<!-- ... -->
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
注Visibility
的結合。 HasErrors
屬性是我上面提到的代理屬性。
最後,使用該樣式在DataGrid
如下
<DataGrid RowHeaderStyle="{StaticResource MyDataGridRowHeaderStyle}"
...
的BoolToVisibilityConverter
的實現可以發現here。