Best practice per le regole di associazione e convalida dei dati WPF


101

Ho un'applicazione WPF molto semplice in cui utilizzo il data binding per consentire la modifica di alcuni oggetti CLR personalizzati. Ora voglio inserire una convalida dell'input quando l'utente fa clic su Salva. Tuttavia, tutti i libri di WPF che ho letto in realtà non dedicano alcuno spazio a questo problema. Vedo che puoi creare ValidationRules personalizzate, ma mi chiedo se questo sarebbe eccessivo per le mie esigenze.

Quindi la mia domanda è questa: esiste una buona applicazione o un articolo di esempio da qualche parte che dimostri le migliori pratiche per la convalida dell'input dell'utente in WPF?

Risposte:


83

Penso che il nuovo modo preferito potrebbe essere quello di utilizzare IDataErrorInfo

Leggi di più qui


3
Ho anche trovato il framework Cinch ( cinch.codeplex.com ), che include una demo della convalida delle best practice in WPF + MVVM e utilizza IDataErrorInfo
Mark Heath

3
In .NET 4.5 è possibile utilizzare INotifyErrorInfo che consente di restituire oggetti anziché solo stringhe.
Peter

24

Dalla documentazione Patterns & Practices di MS :

Convalida dei dati e segnalazione degli errori

Il tuo modello di vista o modello sarà spesso richiesto per eseguire la convalida dei dati e per segnalare eventuali errori di convalida dei dati alla vista in modo che l'utente possa agire per correggerli.

Silverlight e WPF forniscono supporto per la gestione degli errori di convalida dei dati che si verificano durante la modifica di singole proprietà associate ai controlli nella visualizzazione. Per singole proprietà associate a dati a un controllo, il modello o il modello di visualizzazione può segnalare un errore di convalida dei dati all'interno del programma di impostazione delle proprietà rifiutando un valore errato in entrata e generando un'eccezione. Se la proprietà ValidatesOnExceptions sull'associazione dati è true, il motore di associazione dati in WPF e Silverlight gestirà l'eccezione e mostrerà all'utente un segnale visivo della presenza di un errore di convalida dei dati.

Tuttavia, il lancio di eccezioni con proprietà in questo modo dovrebbe essere evitato ove possibile. Un approccio alternativo consiste nell'implementare le interfacce IDataErrorInfo o INotifyDataErrorInfo sul modello di visualizzazione o sulle classi del modello. Queste interfacce consentono al modello o al modello di vista di eseguire la convalida dei dati per uno o più valori di proprietà e di restituire un messaggio di errore alla vista in modo che l'utente possa essere informato dell'errore.

La documentazione prosegue spiegando come implementare IDataErrorInfo e INotifyDataErrorInfo.


3
All'inizio mi sono preoccupato quando ho visto lanciare una raccomandazione di eccezione. felice di vedere che seguito da "lanciare eccezioni con proprietà in questo modo dovrebbe essere evitato ove possibile"
Kenwarner

22
va anche notato che alcuni muppet di Microsoft hanno deciso di non includere INotifyDataErrorInfo in .net4 ma solo in silverlight. è un dolore ..
aL3891

5
@ al3891- questo sarà ordinata in .NET 4.5- msdn.microsoft.com/en-us/library/...
RichardOD

@ aL3891 Esiste un'alternativa per INotifyDataErrorInfo mancante?
AgentKnopf

10

personalmente, sto usando le eccezioni per gestire la convalida. richiede i seguenti passaggi:

  1. nell'espressione di associazione dati, è necessario aggiungere "ValidatesOnException = True"
  2. nel tuo oggetto dati a cui ti stai associando, devi aggiungere il gestore DependencyPropertyChanged dove controlli se il nuovo valore soddisfa le tue condizioni - in caso contrario - ripristini il vecchio valore dell'oggetto (se necessario) e lanci un'eccezione.
  3. nel modello di controllo utilizzato per visualizzare un valore non valido nel controllo, è possibile accedere alla raccolta degli errori e visualizzare il messaggio di eccezione.

il trucco qui è associare solo agli oggetti che derivano da DependencyObject. la semplice implementazione di INotifyPropertyChanged non funzionerebbe: c'è un bug nel framework, che ti impedisce di accedere alla raccolta degli errori.


3

Controlla anche questo articolo . Presumibilmente Microsoft ha rilasciato la loro Enterprise Library (v4.0) dai loro schemi e pratiche in cui coprono l'argomento della convalida, ma dio sa perché non hanno incluso la convalida per WPF, quindi il post sul blog a cui ti sto indirizzando, spiega l'autore fatto per adattarlo. Spero che questo ti aiuti!


2

Potresti essere interessato all'applicazione di esempio BookLibrary di WPF Application Framework (WAF) . Mostra come utilizzare la convalida in WPF e come controllare il pulsante Salva in caso di errori di convalida.


0

Se la tua classe aziendale viene utilizzata direttamente dalla tua interfaccia utente è preferibile utilizzare IDataErrorInfo perché avvicina la logica al loro proprietario.

Se la tua classe aziendale è una classe stub creata da un riferimento a un servizio WCF / XmlWeb, non puoi / non devi usare IDataErrorInfo né lanciare un'eccezione per l'uso con ExceptionValidationRule. Invece puoi:

  • Usa ValidationRule personalizzata.
  • Definisci una classe parziale nel tuo progetto UI WPF e implementa IDataErrorInfo.

1
So che questo è vecchio, ma spero che Alex sia in grado di rispondere. Questa è anche la conclusione a cui sono giunto, ma il problema è che devi scrivere una convalida per (ad esempio) una proprietà "Age" che non può essere maggiore di 100 nella ValidationRule, quindi ripetere la stessa logica nell'interfaccia IDataErrorInfo , che duplica la logica. C'è un modo per aggirare questo?
JFTxJ

Dove duplichi la logica? in una sorta di convalida del server? Immagino che dal tuo commento tu stia convalidando con IDataErrorInfo nell'interfaccia utente e duplicando la convalida nell'oggetto business, vero? In tal caso, è corretto convalidare in entrambi i lati. Gli oggetti di business non possono fidarsi dell'interfaccia utente e devono eseguire la propria convalida (anche se sembra una duplicazione)
Alex Pollan

No, la duplicazione della logica di convalida è nell'IDataErrorInfo e nella regola di convalida personalizzata ... Poiché la regola di convalida personalizzata è l'unico modo per convalidare i dati PRIMA che siano effettivamente aggiornati all'oggetto associato, quella convalida (l'età deve essere inferiore quindi 100) deve essere definito in IDataErrorInfo per restituire un messaggio "per campo", ma deve anche essere implementato nella regola di convalida personalizzata. Ha senso?
JFTxJ
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.