2012-04-17 14 views
12

Próbuję sprawdzić poprawność klasy mojego modelu przy użyciu obiektu IDataErrorInfo, jak podano poniżej.IDataErrorInfo - Początkowo zignoruj ​​błędy przy pierwszym ładowaniu widoku

//Validators 
public string this[string propertyName] { 
    get { 
     string error = null; 

     if (propertyName == "Name") { 
      error = ValidateName(); 
     } 
     return error; 
    } 
} 

Działa to dobrze, z wyjątkiem tego, że po pierwszym załadowaniu widoku zawiera już błędy sprawdzania poprawności. Czy można zignorować/pominąć błędy sprawdzania poprawności, gdy widok jest najpierw ładowany. Czy powszechną praktyką jest pokazywanie błędów podczas wczytywania widoku i zanim użytkownik rozpocznie wprowadzanie danych dla właściwości modelu.

pozdrowienia, Nirvan.

Edytuj:W ten sposób konfiguruję IDataErrorInfo.

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

Zobacz to pytanie: http://stackoverflow.com/questions/1502263/how-to-suppress-validation-when-nothing-is-entered –

+0

@AlexKofman zaznacz to pytanie jako duplikat. Już to zrobiłem. – MikroDel

Odpowiedz

3

Podjęłam następujące podejście i działa. Zasadniczo Model powinien poprawnie rejestrować błędy i mieć je wymienione w słowniku, nawet jeśli obiekt jest właśnie utworzony, a użytkownik nie wprowadził jeszcze żadnego tekstu. Tak więc nie zmieniłem kodu modelu ani kodu sprawdzania IDataErrorInfo. Zamiast tego najpierw ustawiam właściwość Validation.Error Template na wartość początkową {x: Null}. Następnie jest kod do podłączenia zdarzenia LostFocus w TextBox, który zmienia szablon Validation.Error z powrotem na to, czego używam. Aby uzyskać zamianę szablonów i dołączenie obsługi zdarzeń LostFocus do wszystkich aplikacji TextBox w mojej aplikacji, użyłem kilku właściwości zależności. Oto kod, którego użyłem.

Zależność Właściwości i LostFocus Kod:

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); 
       } 
      }; 
     } 
    } 

Jeśli IsDirtyEnabled właściwość zależność jest ustawiony na true, używa zwrotnego dołączyć zdarzenie polu tekstowym za LostFocus do obsługi. Handler po prostu zmienia właściwość dołączoną ShowErrorTemplate na wartość true, co z kolei powoduje, że w wyzwalaczu stylu pola tekstowego pojawia się szablon Validation.Error, gdy pole TextBox traci ostrość.

TextBox Style:

<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> 

To może wydawać się zbyt dużo kodu dla prostych rzeczy, ale potem trzeba to zrobić tylko raz dla wszystkich pól tekstowych używam.

pozdrowienia, Nirvan.

+0

Rozwiązanie Nirvana rozwiązuje problem, jeśli przeniesiesz ten kod do klasy bazowej (na przykład BaseControll), niż możesz wyprowadzić wszystkie kontrolki z tej klasy bazowej i zachować to zachowanie we wszystkich kontrolkach. –

+0

Wiem, że minęło trochę czasu, ale mam do czynienia z tym samym problemem. Twoje rozwiązanie działa idealnie, moje pytanie brzmi, czy komunikat o błędzie sprawdzania poprawności jest taki sam dla wszystkich pól - szablon błędu wskazuje na statyczny zasób - dzięki! – thor2k

1

Czy rzucasz wyjątek w get?

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

Nie, nie odrzucam żadnych wyjątków. Używam interfejsu IDataErrorInfo do sprawdzania poprawności właściwości modelu. – Jatin

+0

Moje wspomnienie polega na tym, że musiałem użyć ValidationRules, aby uzyskać sprawdzanie błędów tylko na zestawie. Niestety nie mam teraz dostępu do tego kodu. – Paparazzi

+0

Dzięki za wysiłek. – Jatin

1

ustawienia reguł w metodzie ValidateName(). Twój widok pokazuje tylko błąd :) sugeruję, że nazwa jest polem obowiązkowym i powinna być wypełniona przez użytkownika, ale nie podoba ci się czerwona ramka, gdy widok jest najpierw ładowany?

użyć dwóch różnych szablonów sterujące dla validation.errortemplate normalnego jednego i jeden za obowiązkowe pola (*) czerwonym

thats drodze zrobiłem to po raz ostatni.

+0

To z pewnością ukryłoby błąd w widoku i mogłoby być możliwym rozwiązaniem. Jednak nadal będę czekał na jakiś czas, na wypadek, gdyby było lepsze rozwiązanie niż to. Dzięki – Jatin

2

spróbuj ustawić kontekst danych PO pokazaniu widoku.

W moim przypadku pomogło to.

Powiązane problemy