2012-11-28 16 views
7

Mam aplikację WPF (.Net 3.5), która używa IDataErrorInfo w ViewModel do sprawdzania poprawności danych wejściowych.IDataErrorInfo: Jak sprawdzić, czy wszystkie właściwości są prawidłowe?

Działa świetnie, użytkownik kontroluje poprawne informacje o interfejsie użytkownika.

Problem polega na tym, że użytkownik może nadal zmieniać wybrany element lub zapisać ten element.

Moje pytanie brzmi: skąd mogę wiedzieć, że wszystkie moje właściwości są ważne? Lub przynajmniej, że wszystkie moje wyświetlane wartości są prawidłowe. Celem jest powiązanie niektórych IsActive w tym wyniku.

+0

Jeśli właściwość błędy nie jest zerowy lub pusty wtedy wystąpi błąd –

+0

Gdzie chcesz się dowiedzieć, czy wszystkie są poprawne? W widoku lub ViewModel? – Blachshma

+0

Myślę, że odpowiedź na to może pomóc: http://stackoverflow.com/questions/104520/wpf-validation-for-whole-form –

Odpowiedz

15

Od Twój komentarz do Twojego realizacji IDataErrorInfo zmienić implementację do tego stylu ....

#region IDataErrorInfo Members 

public string Error 
{ 
    get { return this[null] } 
} 

public string this[string columnName] 
{ 
    get 
    { 
     StringBuilder result = new StringBuilder(); 
     if (string.IsNullOrEmpty(columnName) || columnName == "FirstName") 
     { 
      if (string.IsNullOrEmpty(FirstName)) 
       result.Append("Please enter a First Name\n"); 
     } 
     if (string.IsNullOrEmpty(columnName) || columnName == "LastName") 
     { 
      if (string.IsNullOrEmpty(LastName)) 
       result.Append("Please enter a Last Name\n"); 
     } 
     if (string.IsNullOrEmpty(columnName) || columnName == "Age") 
     { 
      if (Age < = 0 || Age >= 99) 
       result.Append("Please enter a valid age\n"); 
     } 
     return (result.Length==0) ? null : result.Remove(result.Length-1,1).ToString(); 
    } 
} 

#endregion 


public bool IsValid { 
    get { return string.IsNullOrEmpty(this.Error); } 
} 

Następnie w nieruchomości zmienił zdarzeń

if (e.PropertyName == "Error") { 
    OnPropertyChanged(this,new PropertyChangedEventArgs("IsValid")); 
} 
if (e.PropertyName != "Error" && e.PropertyName != "IsValid") { 
    OnPropertyChanged(this,new PropertyChangedEventArgs("Error")); 
} 
+0

Och, właśnie z tego wynika błąd? Nie zrozumiałem, że przed i we wszystkich przykładach znalazłem, to nie zostało zaimplementowane – J4N

+1

@ J4N tak, Błąd ma być podsumowaniem tego, co jest nie tak z samym obiektem, zwykle zrobione jako podsumowanie jak w tej odpowiedzi. –

+0

Zmodyfikowałem swój kod, aby użyć twojego rozwiązania (prawie, wciąż mam właściwość IsValid, która zawiera boolean, i aktualizuję ją w moim elemencie zmiany zdarzenia – J4N

0

Na razie dodałem tę metodę do mojego modelu.

public Boolean IsModelValid() 
    { 
     Boolean isValid = true; 
     PropertyInfo[] properties = GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance); 

     foreach (PropertyInfo p in properties) 
     { 
      if (!p.CanWrite || !p.CanRead) 
      { 
       continue; 
      } 
      if (this[p.Name] != null) 
      { 
       isValid = false; 
      } 
     } 
     return isValid; 
    } 

I związani sam obiekt na zdarzenie PropertyChanged,

public MyClassName() 
    { 
     PropertyChanged += CheckModelValidity; 
     CheckModelValidity(null, null); 
    } 

kiedy to się zmieni, to wywołanie tej metody, a jeśli wynik jest inny niż mój rzeczywistego członka publicznego, zaktualizować go:

private void CheckModelValidity(object sender, PropertyChangedEventArgs e) 
    { 
     bool isModelValid = IsModelValid(); 
     if(isModelValid!= IsValid) 
     { 
      IsValid = isModelValid; 
     } 
    } 

A następnie mogę po prostu związać właściwość IsValid.

Nie wiem, czy istnieje lepsze rozwiązanie?

+5

Nasty, używając refleksji za każdym razem, gdy zmieni się właściwość zdarzenia ... –

+2

Jeśli zamierzasz przejść tę trasę, zainicjuj listę poprawnych nazw właściwości w statycznym konstruktorze przechowującym listę w polu statycznym. Wtedy pojawia się tylko odbicie –

+0

@ Bob Vale Tak, nie jestem z tego dumny, ale wolę to od ryzyka, że ​​ktoś zapomni o zrobieniu jednego czeku. Nice, zainicjuję to w statycznym var. – J4N

Powiązane problemy