L'infrastruttura delle navigation application di Silverlight ci permette di dividere in pagine separate le varie sezioni delle applicazioni, pagine che possiamo visualizzare in sequenza in modo analogo a quanto siamo abituati a fare durante la navigazione di un sito web con un browser internet.
La "navigazione" tra le pagine avviene attraverso l'oggetto NavigationService, esposto direttamente come proprietà dei Page: i controlli che utilizziamo per la definizione dei layout al posto degli UserControl.
Nel contesto di un'applicazione gestita attraverso il pattern Model-View-ViewModel le azioni vengono gestite all'interno dei ViewModel. Per rendere disponibile un'istanza dell'oggetto NavigationService anche al ViewModel della relativa Page possiamo adottare diverse modalità. Nel nostro esempio utilizziamo una attached property sulla Page, in modo che possa trasferire il NavigationService ad una nostra classe che ne incapsula le funzionalità.
Di seguito il codice dell'attached property:
public static class Navigator { public static INavigable GetSource(DependencyObject obj) { return (INavigable)obj.GetValue(SourceProperty); } public static void SetSource(DependencyObject obj, INavigable value) { obj.SetValue(SourceProperty, value); } public static readonly DependencyProperty SourceProperty = DependencyProperty.RegisterAttached("Source", typeof(INavigable), typeof(Navigator), new PropertyMetadata(OnSourceChanged)); private static void OnSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { Page page = (Page)d; page.Loaded += PageLoaded; } private static void PageLoaded(object sender, RoutedEventArgs e) { Page page = (Page)sender; INavigable navSource = GetSource(page); if (navSource != null) { navSource.NavigationService = new NavigationService(page.NavigationService); } } }
Come si può capire dal codice, i ViewModel devono implementare una nostra interfaccia INavigable, cioè esporre una proprietà di tipo INavigationService, interfaccia implementata dalla nostra classe NavigationService, di cui facciamo esplicitamente l'istanza nel codice subito sopra passando come parametro nel costrotture l'oggetto NavigationService della Page associata.
Per utilizzare il tutto dobbiamo valorizzare la proprietà Source dell'attached property con il ViewModel stesso, utilizzando l'espressione di binding come nell'esempio seguente.
<navigation:Page x:Class="SilverlightItalia.Nav.Pages.Page1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation" xmlns:nav="clr-namespace:SilverlightItalia.Nav.Navigation" nav:Navigator.Source="{Binding}"> <Grid x:Name="LayoutRoot"> <TextBlock Text="Pagina1" /> <Button Content="Vai a pagina 2" Command="{Binding GotoPage2Command}" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,27,0,0" /> </Grid> </navigation:Page>
Nel codice allegato è possibile trovare un esempio completo di un'applicazione con due pagine.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Creare una libreria CSS universale: Cards
Ottimizzare le performance delle collection con le classi FrozenSet e FrozenDictionary
Eseguire script pre e post esecuzione di un workflow di GitHub
Creare una libreria CSS universale: Immagini
Evitare (o ridurre) il repo-jacking sulle GitHub Actions
Paginare i risultati con QuickGrid in Blazor
Loggare le query più lente con Entity Framework
Recuperare automaticamente un utente e aggiungerlo ad un gruppo di Azure DevOps
Come EF 8 ha ottimizzato le query che usano il metodo Contains
Eseguire una ricerca avanzata per recuperare le issue di GitHub
Creare una libreria CSS universale: Nav menu
Migliorare la scalabilità delle Azure Function con il Flex Consumption