2009-12-10 24 views
13

Sto lavorando all'applicazione basata su WPF. L'ambiente è VS2008 SP1 con .NET 3.5 SP 1. Nel nostro sviluppo utilizziamo ampiamente lo schema MVVM.Convalida l'associazione dati in XAML in fase di compilazione

I.e. gli sviluppatori di applicazioni scrivono Models e ViewModels (C#), quindi gli sviluppatori di UI scrivono Views usando WPF Binding (XAML). Gli sviluppatori di applicazioni scrivono anche test unitari su ViewModels. Stiamo usando la metodologia di integrazione continua e stiamo testando la generazione e l'esecuzione di unità su ogni modifica

Il problema è una mancanza di processo o strumenti di convalida della correttezza del binding dei dati in XAML. Per esempio:

  1. App sviluppatore scrive proprietà NmberOfApples e unit test per controllarne il corretto comportamento
  2. sviluppatore dell'interfaccia utente crea il controllo dell'utente e associarlo alla proprietà
  3. App sviluppatore rileva che proprietà ha errore ortografico e fissare il suo nome a NumberOfApples
  4. sarebbe errori tempo di compilazione in qualsiasi codice C# utilizza NmberOfApples di proprietà, e tali errori si b e facile da catturare (Continuous Integration)
  5. associazione dei dati nel file XAML non stanno andando a essere convalidato e sarà eseguito l'errore di tempo

La mia domanda sarà “C'è qualche strumento o metodologia che ci aiutano a convalidare correttezza dell'associazione dati in XAML in fase di compilazione? "

+0

Ho scoperto che ho pubblicato un duplicato della tua domanda. :( http: // StackOverflow.it/questions/43208011/detect-in-xaml-broken-bindings-già-at-compile-time Ma sono diventato una buona soluzione! Non pubblicherei una soluzione qui, perché non è da me e altrimenti sarebbe un plagio. – Rekshino

risposta

9

Una soluzione al problema è discussa in questo article.

L'idea di base è di creare un insieme di MetaData ViewModel di classi statiche (C#) che contengono il valore di stringa delle proprietà delle classi ViewModel che è possibile utilizzare in xaml. L'articolo spiega come utilizzare la generazione di testo T4 per creare queste classi di metadati statici. Puoi utilizzare qualsiasi strumento di generazione del codice di tua preferenza.

così il vostro VM ha la seguente:

namespace Mine 
{ 
    public class MyViewModel 
    { 
    public int MyInt {get;set;} 
    public string MyString {get;set;} 
    } 
} 

E la generazione di codice potrebbe creare questa:

namespace Mine.MetaData 
{ 
    public static class MyViewModelMetaData 
    { 
    public const string MyInt = "MyInt"; 
    public const string MyString = "MyString"; 
    } 
} 

e poi nel tuo XAML si dovrebbe aggiungere lo spazio dei nomi per il vostro XAML e legare i controlli alla classe di metadati

<TextBox Text="{Binding Path={x:Static Metadata:MyViewModelMetadata.MyInt}}"/> 

Se si utilizza un componente aggiuntivo come resharper quindi ti darà intellisense sulle proprietà della classe statica e anche perché fai riferimento a una proprietà esatta in una classe statica, quando la classe statica viene rigenerata, xaml non dovrebbe compilare.

È piuttosto lucido, penso sia fantastico e ha la possibilità di mantenere la gente sana di mente, ma il tuo percorso può variare. :)

EDIT:

A proposito, io non comprare i "ViewModels sono strettamente accoppiati alle viste". Secondo me, le View sono inestricabilmente legate ai loro ViewModels, ma dovrebbero essere solo in un modo. ViewModels dovrebbe essere completamente indipendente da qualsiasi implementazione della vista. È come se ViewModel fosse l'interfaccia e View fosse la classe implementata concretamente. Quindi per questo motivo non inserisco alcuna proprietà specifica per WPF (ad esempio enumerazione della visibilità) nel mio ViewModel perché ciò mi vincola ad usare WPF per l'eternità (che non è proprio una cosa negativa :)), ma compromette la manutenzione.

+1

È un ottimo approccio, grazie per averlo indicato. Terrò questa domanda senza risposta per un altro paio di giorni, nel caso in cui qualcuno volesse condividere altri trucchi. –

+0

@Jose Se non si conservano proprietà come "visibilità" nel modello di vista, come si modifica la visibilità del componente dell'interfaccia utente poiché non è possibile incorporare la logica condizionale in XAML? –

1

Esistono numerosi scenari discutibili in cui questo comportamento è effettivamente desiderato. In ogni caso, è di design che i binding ingannano gli errori ed è la ragione per cui non riuscirai a trovare nulla che ti possa aiutare in questo.

La cosa migliore che ho visto è un gestore di convalida eccezioni che mostrerà gli errori di rilegatura: http://msdn.microsoft.com/en-us/library/system.windows.controls.exceptionvalidationrule.aspx

L'argomento di questo è vista e ViewModels sono destinate ad essere disaccoppiato al punto in cui potrebbe essere utilizzato a View per più ViewModels. Aiuta anche nella "Piegabilità" delle viste in modo che teoricamente i tipi di designer possano disegnare una vista senza incorrere in una serie di errori mentre lo fanno. Mi rendo conto che questo potrebbe non adattarsi al tuo processo, ma questa è la storia.

+0

So che è bello avere View e ViewModel disaccoppiato. Domanda qui, come posso convalidare la loro "compatibilità". –

+0

Sì ... so che era la tua domanda. Quello era "discutibilmente". Purtroppo penso che dovrai concentrarti su quel ExceptionValidationRule possibilmente e sui test dell'interfaccia utente automatizzati. So che è un po 'schifoso. –

-1

Sono d'accordo con la risposta precedente. Questo è "in base alla progettazione" e non è possibile controllarlo in fase di compilazione.

Ho anche trovato un dolore.

Il modo migliore e unico che ho trovato è controllare l'output di debug di Visual Studio in fase di esecuzione. Qualsiasi errore di binding verrà stampato non appena si apre la finestra che lo contiene.

Sono d'accordo se si pensa che sia un metodo scadente e inaffidabile, ma dovrebbe funzionare se non si dispone di un numero enorme di finestre. È possibile creare una pratica di prova semi-formale in cui una volta ogni tanto si apre una finestra che cerca specificamente gli errori di binding.

+0

Stai suggerendo di camminare manualmente su tutte le finestre dell'applicazione? –

0

Attualmente stiamo usando Caliburn e unit test nel modo spiegato in questo articolo Testing Bindings In WPF.Lo svantaggio di questa soluzione, lo sviluppatore dell'UI scrive codice che ha solo il significato di convalidare i collegamenti e può essere omesso se MS (o qualcuno) scriverebbe il compilatore di convalida XAML.

2

Se si installa ReSharper, una delle (molte) funzionalità che si otterrà è "ispezione del codice". Una delle cose che questa ispezione rileverà sono casi in cui l'associazione non si risolve in una proprietà nel contesto dei dati. Puoi facilmente filtrare la finestra "Risultati ispezione" per mostrare solo questi problemi.

Si noti che è necessario indicare esplicitamente il tipo di modello di vista nelle risorse XAML affinché funzioni.

Example of ReSharper inspections

1

Sono passati anni da quando la domanda iniziale è stato chiesto e ha risposto, ma come ho appena controllato, la soluzione più semplice potrebbe ottenere da allora. ReSharper sembra offrire Intellisense corretto senza la necessità di generare le classi statiche menzionate nella risposta accettata.

Ma non ho visto l'errore di compilazione come indicato nella risposta accettata. Ho anche provato a usare [XamlCompilation (XamlCompilationOptions.Compile)] senza alcun risultato. Per favore, mi tenga corretto se mi manca qualcosa.

Problemi correlati