2012-04-17 12 views
12

Ich versuche meine Modellklasse mit IDataErrorInfo wie unten angegeben zu validieren.IDataErrorInfo - Ignoriere die Fehler beim ersten Laden der Ansicht.

Dies funktioniert einwandfrei, außer dass beim ersten Laden der Ansicht bereits Validierungsfehler enthalten sind. Ist es möglich, Validierungsfehler zu ignorieren/zu unterdrücken, wenn die Ansicht zum ersten Mal geladen wird. Außerdem ist es gängige Praxis, beim Laden der Ansicht und vor dem Start der Dateneingabe für die Modelleigenschaften Fehler anzuzeigen.

grüße, Nirvan.

Bearbeiten: Dies ist, wie ich IDataErrorInfo einrichten.

<TextBox Text="{Binding Name, ValidatesOnDataErrors=True}" Grid.Row="1" Grid.Column="1" /> 
+4

Siehe diese Frage: http://stackoverflow.com/questions/1502263/how-to-suppress-validation-when-nothing-is-tered –

+0

@AlexKofman markieren diese Frage als duplicate. Ich habe es schon gemacht. – MikroDel

Antwort

3

Ich habe den folgenden Ansatz genommen und es funktioniert. Grundsätzlich sollte das Modell Fehler korrekt aufzeichnen und sie in einem Wörterbuch auflisten lassen, selbst wenn das Objekt gerade instanziiert wird und der Benutzer noch keinen Text eingegeben hat. Daher habe ich meinen Modellcode oder den IDataErrorInfo-Validierungscode nicht geändert. Stattdessen setze ich die Validation.Error Template-Eigenschaft zunächst auf {x: Null}. Dann gibt es Code, um das LostFocus-Ereignis der TextBox zu verkabeln, das die Validation.Error-Vorlage zurück zu dem, was ich verwende, ändert. Um das Austauschen von Vorlagen und das Hinzufügen des LostFocus-Ereignishandlers zu allen TextBoxen in meiner Anwendung zu erreichen, verwendete ich einige Abhängigkeitseigenschaften. Hier ist der Code, den ich benutzt habe.

Abhängigkeitseigenschaften und Lost-Focus-Code:

public static DependencyProperty IsDirtyEnabledProperty = DependencyProperty.RegisterAttached("IsDirtyEnabled", 
      typeof(bool), typeof(TextBoxExtensions), new PropertyMetadata(false, OnIsDirtyEnabledChanged)); 
    public static bool GetIsDirtyEnabled(TextBox target) {return (bool)target.GetValue(IsDirtyEnabledProperty);} 
    public static void SetIsDirtyEnabled(TextBox target, bool value) {target.SetValue(IsDirtyEnabledProperty, value);} 

    public static DependencyProperty ShowErrorTemplateProperty = DependencyProperty.RegisterAttached("ShowErrorTemplate", 
      typeof(bool), typeof(TextBoxExtensions), new PropertyMetadata(false)); 
    public static bool GetShowErrorTemplate(TextBox target) { return (bool)target.GetValue(ShowErrorTemplateProperty); } 
    public static void SetShowErrorTemplate(TextBox target, bool value) { target.SetValue(ShowErrorTemplateProperty, value); } 

    private static void OnIsDirtyEnabledChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args) { 
     TextBox textBox = (TextBox)dependencyObject; 
     if (textBox != null) { 
      textBox.LostFocus += (s, e) => { 
       if ((bool) textBox.GetValue(ShowErrorTemplateProperty) == false) { 
        textBox.SetValue(ShowErrorTemplateProperty, true); 
       } 
      }; 
     } 
    } 

Wenn IsDirtyEnabled Abhängigkeitseigenschaft auf true gesetzt ist, verwendet er den Rückruf der Textbox des Lost-Focus-Ereignis zu einem Handler zu befestigen. Der Handler ändert nur die angefügte Eigenschaft ShowErrorTemplate auf true, was wiederum im Stil-Trigger des Textfelds auslöst, die Validation.Error-Vorlage anzuzeigen, wenn die TextBox den Fokus verliert.

TextBox Styles:

<Style TargetType="{x:Type TextBox}"> 
    <Setter Property="Validation.ErrorTemplate" Value="{StaticResource ValidationErrorTemplate}"/> 
    <Setter Property="gs:TextBoxExtensions.IsDirtyEnabled" Value="True" /> 
    <Style.Triggers> 
     <Trigger Property="gs:TextBoxExtensions.ShowErrorTemplate" Value="false"> 
      <Setter Property="Validation.ErrorTemplate" Value="{x:Null}"/> 
     </Trigger> 
    </Style.Triggers> 
</Style> 

Auch dies mag für eine einfache Sache des Codes viel, aber dann habe ich es für alle Textfelder Ich verwende nur einmal zu tun.

grüße, Nirvan.

+0

Nirvans Lösung führt den Trick aus, wenn Sie diesen Code in eine Basisklasse (zB BaseControl) verschieben, als Sie alle Ihre Controls von dieser Basisklasse ableiten können und dieses Verhalten in allen Ihren Controls hat. –

+0

Ich weiß, es ist eine Weile her, aber ich habe das gleiche Problem. Ihre Lösung funktioniert einwandfrei, meine Frage ist, ob die Validierungsfehlermeldung für alle Felder gleich ist - die Fehlervorlage verweist auf eine statische Ressource - danke! – thor2k

1

Werfen Sie die Ausnahme in den Griff?

public string Name 
{ 
    get { return _name; } 
    set 
    { 
     _name = value; 
     if (String.IsNullOrEmpty(value)) 
     { 
      throw new ApplicationException("Customer name is mandatory."); 
     } 
    } 
} 
+0

Nein, ich mache keine Ausnahmen. Ich verwende die IDataErrorInfo-Schnittstelle, um Modelleigenschaften zu überprüfen. – Jatin

+0

Meine Erinnerung ist, ich musste ValidationRules verwenden, um eine Fehlerüberprüfung nur am Set zu bekommen. Entschuldigung, ich habe momentan keinen Zugriff auf diesen Code. – Paparazzi

+0

Danke für deine Mühe trotzdem. – Jatin

1

Sie legen die Regeln in Ihrer ValidateName() -Methode fest. Ihre Ansicht zeigt nur den Fehler :) Ich schlage vor, dass der Name ein Pflichtfeld ist und vom Benutzer ausgefüllt werden sollte, aber Sie nicht den roten Rand mögen, wenn die Ansicht zuerst geladen wird?

i verwenden zwei verschiedene Steuervorlagen für validation.errortemplate die normale und eine für die Pflichtfelder (ein rotes *)

thats die Art, wie ich es das letzte Mal war.

+0

Das würde sicherlich den Fehler in der Sicht verbergen und könnte eine mögliche Lösung sein. Ich werde jedoch noch einige Zeit warten, falls es eine bessere Lösung als diese gibt. Danke – Jatin

2

versuchen Sie, den Datenkontext einzustellen, NACHDEM die Ansicht angezeigt wurde.

In meinem Fall half das.

Verwandte Themen