All'avvio di una Windows Store app abbiamo la possibilità di mostrare un'immagine come splash screen. Questa viene mostrata il tempo necessario per caricare l'applicazione ma è svincolata dalla logica della stessa. Quindi ci troveremo l'applicazione in esecuzione, ma priva di dati, e quindi non utilizzabile dall'utente.
Intervenendo sul flusso d'esecuzione all'avvio dell'applicazione e utilizzando la classe SplashScreen possiamo mantenere l'immagine visualizzata e mostrare un'animazione di caricamento fin quando l'applicazione non avrà recuperato i dati necessari al suo funzionamento.
Per prima cosa aggiungiamo alla solution del nostro progetto un nuovo UserControl, e modifichiamo lo XAML come nell'esempio seguente.
<UserControl.Resources> <Storyboard x:Name="EnterLoadingStoryBoard"> <DoubleAnimation Duration="0:0:0.6" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="ProgressRing" d:IsOptimized="True" /> <DoubleAnimation Duration="0:0:0.6" To="0" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Storyboard.TargetName="ProgressRing" d:IsOptimized="True" /> </Storyboard> </UserControl.Resources> <Canvas Background="#FF6600"> <Image x:Name="logoImage" Source="Assets/SplashScreen.png" Stretch="None" Width="620" Height="300" /> <ProgressRing x:Name="ProgressRing" Height="80" Width="80" IsActive="True" Foreground="Black" Opacity="0" RenderTransformOrigin="0.5,0.5"> <ProgressRing.RenderTransform> <CompositeTransform TranslateY="20" /> </ProgressRing.RenderTransform> </ProgressRing> </Canvas>
L'interfaccia dello UserControl è estremamente semplice, è composta dall'immagine utilizzata come splash screen e da un ProgressRing, in più abbiamo aggiunto una semplice animazione per rendere l'entrata della ProgressRing più piacevole.
E' il momento di modificare il flusso d'esecuzione. Apriamo il file App.xaml.cs e identifichiamo il metodo OnLaunched modificandolo come segue.
protected override void OnLaunched(LaunchActivatedEventArgs args) { if (args.PreviousExecutionState != ApplicationExecutionState.Running) { Window.Current.Content = new PreloadSplashScreen(args.SplashScreen); } Window.Current.Activate(); }
Il metodo OnLaunch riceve come parametro un'istanza dell'oggetto LaunchActivatedEventArgs, a noi interessa la proprietà del tipo SplashScreen, che useremo per inizializzare una nuova istanza dello UserControl aggiunto in precedenza al progetto. L'istanza così ottenuta viene impostata come contenuto della Window corrente e resa attiva.
Torniamo all'UserControl e modifichiamo il costruttore nel code behind come segue.
public PreloadSplashScreen(SplashScreen splashScreen) : this() { splashScreen.Dismissed += splashScreen_Dismissed; Canvas.SetLeft(this.logoImage, splashScreen.ImageLocation.Left); Canvas.SetTop(this.logoImage, splashScreen.ImageLocation.Top); Canvas.SetLeft(this.ProgressRing, splashScreen.ImageLocation.Left + logoImage.Width / 2 - ProgressRing.Width / 2); Canvas.SetTop(this.ProgressRing, splashScreen.ImageLocation.Bottom); //Inizio il caricamento delle risorse PreLoadData(); }
Nel costruttore come prima cosa ci registriamo all'evento Dismissed, così da poter gestire la chiusura della splash. Proseguiamo posizionando l'immagine della splash contenuta nell'UserControl esattamente dove era posizionata quella all'avvio dell'applicazione. Questa operazione può essere compiuta comodamente utilizzando la proprietà ImageLocation del tipo Rect.
Posizionare esattamente la splash screen consente di non notare la transizione dall'immagine usata all'avvio a quella presente nell'UserControl.
Una volta terminato il posizionamento degli elementi dell'UI iniziamo il caricamento dei dati richiamando il metodo PreLoadData.
private async void PreLoadData() { //Simulo operazioni lunghe await Task.Delay(2500); //Creo un nuovo frame var rootFrame = new Frame(); //Navigo rootFrame.Navigate(typeof(MainPage)); //Imposto il contenuto corrente dell'applicazione Window.Current.Content = rootFrame; }
Trattandosi di una demo, simuliamo l'attesa dovuta alle chiamate remote e quanto altro necessario a popolare di dati l'applicazione, mediante il metodo Task.Delay(2500). Successivamente creiamo una nuova istanza dell'oggetto Frame e navighiamo alla home. Infine impostiamo il frame come contenuto della Window.
Diamo un ultimo tocco eseguendo nell'event handler splashScreen_Dismissed l'animazione d'entrata creata per la ProgressRing.
void splashScreen_Dismissed(Windows.ApplicationModel.Activation.SplashScreen sender, object args) { this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, ((Storyboard)Resources["EnterLoadingStoryBoard"]).Begin); }
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Sfruttare il portale Azure per creare script di automazione
Scoprire le ottimizzazioni di Entity Framework Core in fase di scrittura di un solo record
Aggiungere le issue di più repository in una board in GitHub
Migrare un repository che contiene large file storage objects in GitHub
Le novità di .NET 7 e C# 11
Centrare elementi in HTML tramite CSS
Le novità di Entity Framework (Core) 7
Definire lo stile CSS in base alle dimensioni del container
Le novità di .NET 7 e C# 11
Installazione di una PWA Blazor
Personalizzare le richieste con i rule set di Azure Front Door
Migrare un progetto ASP.NET Core da .NET 6 a .NET 7
I più letti di oggi
- .NET Conference Italia 2022 - Milano e Online
- Visual Studio 2019 sarà disponibile a partire dal 2 Aprile
- Windows Phone 8.1 Day - Milano
- Speciale per il lancio di Visual Studio 2008, SQL Server 2008 e Windows Server 2008 dal 25/02 al 07/03
- ASP.NET 3.5 Extensions in beta la settimana prossima
- ASPItalia.com Future Web Conference: 15 gennaio 2008, L'Aquila
- Rilasciata la CTP Preview di ASP.NET 3.5 Extensions
- Tutto per portare Visual Studio 2015, ASP.NET 5 e Windows 10 sotto l'ombrellone!
- Real Code Day 4.0: costruire applicazioni reali - Firenze
- Tutto per portarsi il .NET Framework 3.5 sotto l'ombrellone