2012-11-28 13 views
7

Ho un'applicazione WPF (.Net 3.5) che utilizza IDataErrorInfo sul ViewModel per convalidare l'input.IDataErrorInfo: come sapere se tutte le proprietà sono valide?

Funziona alla grande, l'usercontrol ottiene il feedback dell'interfaccia utente corretto.

Il problema è che l'utente può ancora modificare l'elemento selezionato o salvare questo elemento.

Quindi la mia domanda è: come posso sapere che tutte le mie proprietà sono valide? O almeno che tutti i miei valori visualizzati sono validi. L'obiettivo è di legare alcuni IsActive a questo risultato

+0

Se la proprietà errori non è nullo o vuoto allora ci sarà un errore –

+0

Dove vuoi sapere se sono tutti validi? Nella vista o nel ViewModel? – Blachshma

+0

Penso che la risposta a questo potrebbe aiutarti: http://stackoverflow.com/questions/104520/wpf-validation-for-the-whole-form –

risposta

15

Dal tuo commento sul tuo realizzazione di IDataErrorInfo cambiare l'implementazione di questo stile ....

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

Poi, nel tuo proprietà modificata evento

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

Oh, questo è il motivo per cui l'errore è valido? Non l'ho capito prima e in tutti gli esempi che ho trovato, questo non è stato implementato – J4N

+1

@ J4N sì, l'errore dovrebbe essere un riepilogo di ciò che è sbagliato con l'oggetto stesso, di solito fatto come un sommario come in questa risposta. –

+0

Ho modificato il mio codice per usare la soluzione (quasi, ho ancora una proprietà IsValid che contiene un booleano e la aggiorno nel mio evento change element. – J4N

0

Per ora, ho aggiunto questo metodo sul mio modello.

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

ho legato l'oggetto stesso sull'evento PropertyChanged,

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

quando si cambia, io chiamo questo metodo, e se il risultato è diverso dal mio membro pubblico vero e proprio, mi aggiorno:

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

E quindi posso semplicemente associare la proprietà IsValid.

Non so se esiste una soluzione migliore?

+5

Cattivo, utilizzando la riflessione ogni volta che si verifica un evento modificato proprietà .... –

+2

Se si intende percorrere questa rotta, inizializzare l'elenco di nomi di proprietà validi nel costruttore statico che lo memorizza in un campo statico. Quindi il riflesso si verifica solo una volta –

+0

@BobVale Sì, non ne sono orgoglioso, ma preferisco questo al rischio che qualcuno si dimentichi di fare un controllo. Bello, lo inizializzerò in una variabile statica. – J4N

Problemi correlati