Dati di esempio nell'area di progettazione e per la creazione di prototipi
Nota
Il grado di necessità dei dati di esempio e la loro utilità dipende dal fatto che i vincoli utilizzino l'estensione di {Binding} markup extension o {x:Bind} markup extension. Le tecniche descritte in questo argomento sono basate sull’uso di un DataContext, dunque sono adatte solo a {Binding}. Se invece usi {x:Bind}, i tuoi binding mostrano nell’area di progettazione almeno valori segnaposto, anche per i controlli elementi, dunque non avrai altrettanto bisogno di dati di esempio.
Può essere impossibile o indesiderabile, ad esempio per motivi di privacy o di prestazioni, che la tua app visualizzi dati reali nell’area di progettazione in Microsoft Visual Studio o Blend per Visual Studio. Esistono vari modi per usare dati di esempio in fase di progettazione per popolare i controlli con i dati, in modo da poter lavorare sul layout dell'app, i modelli e altre proprietà visive. I dati di esempio possono essere molto utili e permetterti di risparmiare parecchio tempo anche se stai compilando una bozza di app, ovvero un prototipo. Puoi usare i dati di esempio nel prototipo in fase di esecuzione per illustrare le tue idee senza bisogno di connetterti a dati reali.
App di esempio che illustrano {Binding}
- Scarica l'app Bookstore1.
- Scarica l'app Bookstore2.
Nota
Gli screenshot presenti in questo articolo sono stati acquisiti da una versione precedente di Visual Studio. Se si usa Visual Studio 2019, potrebbero non corrispondere esattamente all'esperienza di sviluppo.
Impostazione del DataContext nel markup
Per gli sviluppatori è prassi comune usare codice imperativo (nel code-behind) per impostare il DataContext di una pagina o un controllo utente su un’istanza del modello di visualizzazione.
public MainPage()
{
InitializeComponent();
this.DataContext = new BookstoreViewModel();
}
Se fai questo, però, la tua pagina sarà meno semplice da progettare. Il motivo è che quando la pagina XAML viene aperta in Visual Studio o Blend per Visual Studio, il codice imperativo che assegna il valore DataContext non viene mai eseguito (di fatto non viene eseguito alcun file code-behind). Gli strumenti XAML, naturalmente, analizzano il markup e creano istanze di tutti gli oggetti dichiarati, ma non creano effettivamente un'istanza del tipo della pagina. Il risultato è che non vedrai dati nei controlli o nella finestra di dialogo Crea associazione dati e lavorare sullo stile e sul layout della pagina sarà più difficile.
Il primo rimedio da provare è impostare come commento l’assegnazione DataContext e impostare il DataContext nel markup della pagina. In questo modo, i tuoi dati reali verranno visualizzati sia in fase di progettazione che in fase di esecuzione. Per fare questo, come prima cosa apri la pagina XAML. Quindi, nella finestra Struttura documento fai clic sull'elemento radice progettabile (in genere con l'etichetta [Page])per selezionarlo. Nella finestra Proprietà trovare la proprietà DataContext (all'interno della categoria Comuni) e modificarla. Selezionare il tipo di modello di visualizzazione nella finestra di dialogo Seleziona oggetto e quindi fare clic su OK.
Questo è l'aspetto del markup risultante.
<Page ... >
<Page.DataContext>
<local:BookstoreViewModel/>
</Page.DataContext>
Ed ecco come appare l'area di progettazione ora che è possibile risolvere i binding. Nota che il selettore Percorso nella finestra di dialogo Crea associazione dati ora è popolato, in base al tipo di DataContext e alle proprietà a cui puoi eseguire il binding.
La finestra di dialogo Crea associazione dati ha bisogno solo di un tipo da cui lavorare, ma i binding hanno bisogno che le proprietà siano inizializzate con valori. Se non vuoi contattare il tuo servizio cloud in fase di progettazione, ad esempio per problemi di prestazioni, per non pagare il trasferimento di dati, per questioni di privacy e così via, il tuo il codice di inizializzazione può controllare se l'app è in esecuzione in uno strumento di progettazione (ad esempio Visual Studio o Blend per Visual Studio) e in tal caso caricare dati di esempio da usare solo in fase di progettazione.
if (Windows.ApplicationModel.DesignMode.DesignModeEnabled)
{
// Load design-time books.
}
else
{
// Load books from a cloud service.
}
Se devi passare parametri al codice di inizializzazione, puoi usare un localizzatore del modello di visualizzazione. Un localizzatore del modello di visualizzazione è una classe che puoi inserire nelle risorse dell'app. Ha una proprietà che espone il modello di visualizzazione e il DataContext della pagina esegue il binding a questa proprietà. Un altro pattern che il localizzatore o il modello di visualizzazione può usare è l'inserimento delle dipendenze, che può costruire un provider di dati in fase di progettazione o in fase di esecuzione (ognuno dei quali implementa un'interfaccia comune), a seconda dei casi.
Dati di esempio da classe e attributi della fase di progettazione
Se per qualsiasi motivo nessuna delle opzioni nella sezione precedente ti consente di risolvere il problema, hai comunque a disposizione molte opzioni per i dati in fase di progettazione tramite le funzionalità degli strumenti XAML e gli attributi della fase di progettazione. Un’opzione efficace è la funzionalità Crea dati di esempio da classe in Blend per Visual Studio. Puoi trovare il comando su uno dei pulsanti nella parte superiore del pannello Dati.
Tutto quello che devi fare è specificare una classe per il comando. Fatto questo, il comando esegue per te due operazioni importanti. Prima di tutto, genera un file XAML che contiene dati di esempio adatti per attivare in modo ricorsivo un'istanza della classe scelta e tutti i relativi membri. Gli strumenti funzionano altrettanto bene con i file XAML e JSON. In secondo luogo, popola il pannello Dati con lo schema della classe scelta. Potrai quindi trascinare i membri dal pannello Dati all’area di progettazione per eseguire svariate attività. In base a ciò che trascini e al punto in cui lo rilasci, puoi aggiungere binding ai controlli esistenti (usando {Binding}) oppure creare nuovi controlli ed eseguire binding allo stesso tempo. In entrambi i casi, l’operazione imposta anche un contesto dei dati in fase di progettazione (d:DataContext), se non è già impostato, nella radice del layout della pagina. Il contesto dei dati in fase di progettazione usa l’attributo d:DesignData per ottenere i dati di esempio dal file XAML generato, che tra l’altro sei libero di cercare nel progetto e modificare in modo che contenga i dati di esempio desiderati.
<Page ...
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid ... d:DataContext="{d:DesignData /SampleData/RecordingViewModelSampleData.xaml}"/>
<ListView ItemsSource="{Binding Recordings}" ... />
...
</Grid>
</Page>
Le varie dichiarazioni xmlns vogliono dire che gli attributi con prefisso d: vengono interpretati solo in fase di progettazione e vengono ignorati in fase di esecuzione. Quindi, l’attributo d:DataContext influisce sul valore della proprietà DataContext solo in fase di progettazione e non ha alcun effetto in fase di esecuzione. Puoi anche impostare sia d:DataContext che DataContext nel markup, se preferisci. d:DataContext avrà la precedenza in fase di progettazione e DataContext avrà la precedenza in fase di esecuzione. Le stesse regole di override si applicano a tutti gli attributi della fase di progettazione e della fase di esecuzione.
L’attributo d:DataContext, con tutti gli altri attributi della fase di progettazione, è documentato nell’argomento Attributi della fase di progettazione, valido anche per le app UWP (Universal Windows Platform).
CollectionViewSource non ha una proprietà DataContext ma ha una proprietà Source. Di conseguenza, esiste una proprietà d:Source che puoi usare per impostare dati di esempio per la sola fase di progettazione su una CollectionViewSource.
<Page.Resources>
<CollectionViewSource x:Name="RecordingsCollection" Source="{Binding Recordings}"
d:Source="{d:DesignData /SampleData/RecordingsSampleData.xaml}"/>
</Page.Resources>
...
<ListView ItemsSource="{Binding Source={StaticResource RecordingsCollection}}" ... />
...
Per far sì che funzioni, devi avere una classe denominata Recordings : ObservableCollection<Recording>
e modificare il file XAML di dati di esempio in modo che contenga solo un oggetto Recordings (contenente oggetti Recording), come illustrato qui.
<Quickstart:Recordings xmlns:Quickstart="using:Quickstart">
<Quickstart:Recording ArtistName="Mollis massa" CompositionName="Cubilia metus"
OneLineSummary="Morbi adipiscing sed" ReleaseDateTime="01/01/1800 15:53:17"/>
<Quickstart:Recording ArtistName="Vulputate nunc" CompositionName="Parturient vestibulum"
OneLineSummary="Dapibus praesent netus amet vestibulum" ReleaseDateTime="01/01/1800 15:53:17"/>
<Quickstart:Recording ArtistName="Phasellus accumsan" CompositionName="Sit bibendum"
OneLineSummary="Vestibulum egestas montes dictumst" ReleaseDateTime="01/01/1800 15:53:17"/>
</Quickstart:Recordings>
Se usi un file di dati di esempio JSON anziché XAML, devi impostare la proprietà Type.
d:Source="{d:DesignData /SampleData/RecordingsSampleData.json, Type=local:Recordings}"
Finora abbiamo usato d:DesignData per caricare i dati di esempio in fase di progettazione da un file XAML o JSON. In alternativa si può usare l’estensione di markup d:DesignInstance, che indica che l’origine in fase di progettazione è basata sulla classe specificata dalla proprietà Type. Ecco un esempio.
<CollectionViewSource x:Name="RecordingsCollection" Source="{Binding Recordings}"
d:Source="{d:DesignInstance Type=local:Recordings, IsDesignTimeCreatable=True}"/>
La proprietà IsDesignTimeCreatable indica che lo strumento di progettazione deve effettivamente creare un'istanza della classe. Questo implica che la classe ha un costruttore pubblico predefinito e che questo acquisisce dati (reali o di esempio). Se non imposti IsDesignTimeCreatable o se lo imposti su False, i dati di esempio non verranno visualizzati nell'area di progettazione. Tutto ciò che lo strumento di progettazione fa, in questo caso, è analizzare la classe cercando le proprietà associabili e visualizzarle nel pannello Dati e nella finestra di dialogo Crea data binding.
Dati di esempio per la creazione di prototipi
Per la creazione di prototipi, hai bisogno di dati di esempio sia in fase di progettazione che in fase di esecuzione. Per questo caso d'uso, Blend per Visual Studio offre la funzionalità Nuovi dati di esempio. Puoi trovare il comando su uno dei pulsanti nella parte superiore del pannello Dati.
Anziché specificare una classe, puoi progettare lo schema dell'origine dati di esempio direttamente nel pannello Dati. Puoi anche modificare i valori dei dati di esempio nel pannello Dati senza bisogno di aprire e modificare un file (puoi comunque farlo, se preferisci).
La funzionalità Nuovi dati di esempio usa DataContext e non d:DataContext, in modo che i dati di esempio siano disponibili quando esegui il prototipo, ma anche mentre lo progetti. Il pannello Dati velocizza moltissimo le attività di progettazione e binding. Ad esempio, semplicemente trascinando una proprietà raccolta dal pannello Dati vengono generati un controllo elementi associato a dati e i modelli necessari, pronti per la compilazione e l'esecuzione.