Entwickler-Ecke

WPF / Silverlight - XAML ValidationRules im ViewModel CanExecute verwenden


RobAll - Do 08.04.21 11:38
Titel: XAML ValidationRules im ViewModel CanExecute verwenden
Hallo Zusammen,

Im XAML nutze ich zur Validierung einer Adresse

XML-Daten
1:
2:
3:
<Binding.ValidationRules>
  <vr:AdressValidationRule />
</Binding.ValidationRules>


C#-Quelltext
1:
2:
3:
4:
5:
//Validierungsklasse
public class AdressValidationRule : ValidationRule
{
  //...
}

Diese Validierung möchte ich nun im ViewModel "CanExecute" eines CommandBinding nutzen.

Die Lösung über XAML Has Error will ich nicht verwenden

XML-Daten
1:
<DataTrigger Binding="{Binding ElementName=Adresse, Path=(Validation.HasError)}"                    


Kann ich den Error aus dem XAML ins ViewModel binden und für das CanExecute verwenden?

Welche Lösung verwendet ihr?

Danke vorab
Rob ALL

Moderiert von user profile iconTh69: XML-Tags hinzugefügt
Moderiert von user profile iconTh69: C#-Tags hinzugefügt


Th69 - Do 08.04.21 15:40

Du kannst doch einfach ein Objekt deiner ValidationRule-Klasse erstellen und dessen Validate [https://docs.microsoft.com/de-de/dotnet/api/system.windows.controls.validationrule.validate?view=net-5.0]-Methode aufrufen.


RobAll - Fr 09.04.21 16:21

Th69 erstmal danke..

Dein Vorschlag funktioniert fast..

Die Validation Rule verhindert einen korrupten Wert in der gebundenen Eigenschaftsmethode, erstmal gut, aber die "e.CanExecute = true" bleibt true.

- Wie kann ich explizit einen korrupten Wert über XAML ins ViewModel Feld binden, um mit dem Command zu arbeiten?
Irgendwie widerspricht sich das? Gibt es noch eine andere Möglichkeit zu meiner ursprünglichen Frage?

- Die ValidationRule erwartet als zweites Argument CultureInfo hier übergebe ich null -> Für was wird diese benötigt?

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
private void OpenCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
    if (AdressValidationRule.Validate(Adress, null).IsValid)
    {
        e.CanExecute = true;
    }
    else
    {
        e.CanExecute = false;
    }
}


Moderiert von user profile iconTh69: C#-Tags hinzugefügt


Th69 - Fr 09.04.21 17:18

Dort solltest du CultureInfo.CurrentCulture [https://docs.microsoft.com/de-de/dotnet/api/system.globalization.cultureinfo.currentculture?view=net-5.0] verwenden.

Deine Frage verstehe ich jedoch nicht!?


RobAll - Fr 09.04.21 18:19

Hallo Th69

Die Validation Rule lässt nur einen gültigen Wert im Setter
zu:

C#-Quelltext
1:
2:
3:
set {
    SetProperty(ref _Adress, value);                
}

ungültige Werte werden nicht ins Modell geupdatet. Erstmal gut, aber

wie kann e.CanExecute des Commands reagieren, wenn die Eigenschaft "Adress" nur gültige Werte annimmt?


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
private void OpenCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
    if (AdressValidationRule.Validate(Adress, null).IsValid)
    {
        e.CanExecute = true;
    }
    else
    {
        e.CanExecute = false;
    }
}

Moderiert von user profile iconTh69: C#-Tags hinzugefügt


Th69 - Sa 10.04.21 09:51

Ok, jetzt verstehe ich (hoffentlich). Vllt. hilft dir MVVM - Command und ValidationRule - Problem [https://mycsharp.de/forum/threads/107703/mvvm-command-und-validationrule-problem]?

Ansonsten gibt es ja noch andere Validierungsmöglichkeiten, s. z.B. Data Validation in WPF [https://andydunkel.net/2019/10/16/data-validation-in-wpf/].
How to call CanExecute when validation cancels UpdateSourceTrigger [https://stackoverflow.com/questions/34927858/how-to-call-canexecute-when-validation-cancels-updatesourcetrigger] verwendet IDataErrorInfo.

PS: Bitte verwende selber die passenden C#- oder XML-Tags in deinen Beiträgen.