ValidationRules - geprüften Wert trotz Validierungsfehler in Binding zurückschreiben

  • WPF MVVM
  • .NET (FX) 4.5–4.8

    ValidationRules - geprüften Wert trotz Validierungsfehler in Binding zurückschreiben

    Guten Morgen :)

    ich hab mal eine ganz kurze Frage:

    Und zwar hab ich eine Liste mit Datensätzen in einem DataGrid. Auf manche der Spalten wende ich ValidationRules an:

    Spoiler anzeigen

    XML-Quellcode

    1. <DataGridTextColumn Header="Track #" Width="60" EditingElementStyle="{StaticResource txtTrackNummer}">
    2. <DataGridTextColumn.Binding>
    3. <Binding Path="Tracknummer" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay">
    4. <Binding.ValidationRules>
    5. <viewmodel:TrackNummerRule ValidatesOnTargetUpdated="True"/>
    6. </Binding.ValidationRules>
    7. </Binding>
    8. </DataGridTextColumn.Binding>
    9. </DataGridTextColumn>



    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class TrackNummerRule
    2. Inherits ValidationRule
    3. Public Overrides Function Validate(value As Object, cultureInfo As Globalization.CultureInfo) As ValidationResult
    4. Dim TrackNr As Integer
    5. If Integer.TryParse(CType(value, String), TrackNr) Then
    6. If (TrackNr > 0) And (TrackNr < 1000) Then
    7. Return ValidationResult.ValidResult
    8. End If
    9. End If
    10. Return New ValidationResult(False, "Ungültige Tracknummer. Bitte gebe einen Wert von 1-999 ein.")
    11. End Function
    12. End Class


    Jetzt hab ich noch einen Button zum Speichern der Datensätze. Ich möchte, dass, wenn ich irgendwo im DataGrid einen ungültigen Wert eingebe, das Speichern nicht möglich ist.

    Also hab ich mir eine Funktion geschrieben, die beim Klick des Buttons ausgeführt wird:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Function ValidateMetaData(argTitelListe As List(Of ViewModel.MP3FileInfoVM)) As Boolean Implements IChangeMetaData.ValidateMetaData
    2. For Each Eintrag In argTitelListe
    3. If Not (TrackNummerValidator.Validate(Eintrag.Tracknummer, Nothing) = ValidationResult.ValidResult) Then
    4. Return False
    5. End If
    6. '[usw. mit den anderen Spalten...]
    7. Next
    8. Return True
    9. End Function


    Blöd ist nur, dass wenn ich einen falschen Wert eingebe, die Funktion trotzdem immer True zurückgibt weil, ich hab es getestet, der falsche Wert nicht zurückgeschrieben wird in die TitelListe, sondern nur der letzte richtige, weil das die Validation verhindert.

    Gibt es da evtl. eine Property oder sowas, die das verhindert. Oder beziehungsweise wie würdet ihr das lösen?

    Edit: Habs gefunden, lag an der ValidationStep Property:

    XML-Quellcode

    1. <viewmodel:TrackNummerRule ValidatesOnTargetUpdated="True" ValidationStep="CommittedValue"/>


    Danach hatte ich noch einen Konvertierungsfehler, da hab ich das hier noch geändert (zweiter Spoiler):

    VB.NET-Quellcode

    1. If Integer.TryParse(value.ToString, TrackNr) Then


    Edit2:
    Und dann ist noch ein Problem aufgetaucht:
    Die Cells im DataGrid wurden rot umrandet, obwohl der Wert valid war. Nach Stunden der Recherche hab ich dann auch dafür eine Lösung gefunden:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Function GetBoundValue(ByVal value As Object) As Object
    2. If TypeOf value Is BindingExpression Then
    3. Dim binding As BindingExpression = CType(value, BindingExpression)
    4. Dim resolvedPropertyName As String = binding.[GetType]().GetProperty("ResolvedSourcePropertyName", BindingFlags.[Public] Or BindingFlags.DeclaredOnly Or BindingFlags.Instance).GetValue(binding, Nothing).ToString()
    5. Dim resolvedSource As Object = binding.[GetType]().GetProperty("ResolvedSource", BindingFlags.[Public] Or BindingFlags.DeclaredOnly Or BindingFlags.Instance).GetValue(binding, Nothing)
    6. Dim propertyValue As Object = resolvedSource.[GetType]().GetProperty(resolvedPropertyName).GetValue(resolvedSource, Nothing)
    7. Return propertyValue
    8. Else
    9. Return value
    10. End If
    11. End Function


    Und der Aufruf der Konvertierung in der Function Validate so, z.B. für einen String:

    VB.NET-Quellcode

    1. Dim str As String = TryCast(GetBoundValue(value), String)


    Dieser Beitrag wurde bereits 6 mal editiert, zuletzt von „kafffee“ ()