Stellen Sie sich ein DataGrid vor, dessen ItemsSource
auf ObservableCollection
festgelegt ist. Diese Sammlung bietet ein Ansichtsmodell für jede Zeile in der DataGrid
. Das Ansichtsmodell wiederum liefert die Daten, die in einer Zeile angezeigt werden, und einen Befehl, der diese Daten ändern kann. Außerdem fügte ich der RowValidationRules
-Eigenschaft von DataGrid
eine Regel hinzu. Diese Validierungsregel funktioniert einwandfrei, wenn ich ungültige Daten eingabe.Überprüfen Sie die Zeile, wenn sich die zugrunde liegenden Daten ändern
Wenn ich die ungültigen Daten jedoch über den Befehl, den das Ansichtsmodell bereitstellt, in gültige Daten umwandelt, wird die Zeilenüberprüfungsregel nur erneut ausgelöst, wenn die aktuelle Zeile in DataGrid
den Fokus verliert. Daher können die angezeigten Daten tatsächlich gültig sein, aber die DataGrid
zeigt immer noch ein rotes Ausrufezeichen mit ungültigen Daten an. Dies bleibt der Fall, bis die aktuelle Zeile den Fokus verliert oder ich wieder gültige Daten eingib.
Wie erzwinge ich eine zweite Validierung der aktuellen Zeile? Ich habe bereits ValidatesOnTargetUpdated="True"
gesetzt, aber das hat das Problem nicht gelöst. Ich habe auch die INotifyPropertyChanged-Schnittstelle implementiert, aber das hat das Problem auch nicht behoben.
Lösung
Als Benutzer mm8 darauf hingewiesen, INotifyDataErrorInfo
ist der Ansatz zu gehen. Ich habe die Zeilenüberprüfungsregel entfernt und eine Eigenschaft mit dem Namen HasErros
in meinem Ansichtsmodell verfügbar gemacht, die die HasErrors
-Eigenschaft meines Modells repliziert, die wiederum INotifyDataErrorInfo
implementiert. Als nächstes habe ich eine benutzerdefinierte 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>
und erstellt den folgenden benutzerdefinierten Stil für 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>
Hinweis von Visibility
die Bindung. Die HasErrors
-Eigenschaft ist die oben erwähnte Proxy-Eigenschaft.
Und schließlich, diesen Stil in der DataGrid
verwenden als
<DataGrid RowHeaderStyle="{StaticResource MyDataGridRowHeaderStyle}"
...
Eine Implementierung BoolToVisibilityConverter
folgt here gefunden werden kann.