Technology Experience
.NET World

Ricordare la posizione delle Window di WPF usando MVVM

Una delle caratteristiche che trovo simpatiche in un’applicazione Windows è quando si ricorda la posizione e la dimensione delle finestre. Questa cosa diventa ancora più utile se si utilizza più di un monitor, perchè a questo punto la nostra applicazione si ricorderà di aprire le finestre anche sull’eventuale monitor secondario, ridimensionate e nella stessa identica posizione in cui la avevamo lasciate l’ultima volta.

Fare questa cosa con il code-behind è piuttosto banale, perchè basta gestire gli eventi Closed e Loaded delle finestre: nel primo caso bisogna salvare da qualche parte posizione e dimensione, nel secondo caso bisogna leggerle e ripristinarle.

E se volessi implementare questo meccanismo in un’applicazione enterprise sviluppata con MVVM? Magari scrivendo un codice XAML di questo tipo:

<Window x:Class="AppDiProva.UI.WPF.Views.LoginWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:helper="clr-namespace:Helpers.Xaml"
        Title="Titolo" Height="370" Width="500" ResizeMode="NoResize"
        
        helper:WindowStateHelper.Active="True">
</Window>

 

Ho volutamente lasciato una riga spaziata per evidenziare l’helper che utilizzo, e che ovviamente mi sono scritto per gestire questo scenario. In pratica, si tratta di una classe WindowStateHelper, con una sola dependency property booleana, che imposto a “True”. Quando viene attivata, come nell’esempio qui sopra, internamente fa tutto quanto il lavoro, che può essere riassunto così:

  1. sottoscrive gli eventi Closed e Loaded della Window
  2. quando una finestra viene chiusa, salvo in un semplice file di testo la dimensione e la posizione della finestra; il nome del file viene generato prendendo in pratica il nome della classe, sostituendo ogni “.” con “-“, giusto per rendere il nome del file gradevole. Quindi lo stato di una Window con nome VivendoByte.MioSoftware.UI.LoginWindow verrebbe salvato nel file “VivendoByte-MioSoftware-UI-LoginWindow.txt”
  3. quando una finestre viene riaperta, controllo se esiste un file che contiene il suo stato (prendo il nome della classe, come nel punto 2): se esiste, lo leggo e lo decodifico, e reimposto dimensione e posizione. Se non esiste, significa che è la prima volta che è stata aperta, per cui non faccio nulla
  4. I files vengono salvati nella directory Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\Mio Programma\"; evitate la cartella di roaming, perchè in questo modo andreste a sincronizzare i files sugli altri PC con cui vi loggate con lo stesso Microsoft Account. E quindi significa che se su un PC avete due monitor Full HD, e su un notebook avete una vetusta 1366×768, le finestre potrebbero non comparire perchè al di fuori dell’area visibile

Lo trovo piuttosto elegante, e soprattutto molto trasparente, perchè il developer finale dell’applicazione non si accorge di nulla. Lui sa che lo stato delle finestre viene salvato e ripristinato, e tanto basta, senza troppe complicazioni e concentrandosi sulla sua applicazione finale.

Il codice dell’helper è scaricabile da qui. E’ sicuramente migliorabile, ma è un buon punto di partenza.

Send to Kindle

Igor Damiani

La sua passione per l'informatica nasce nella prima metà degli anni '80, quando suo padre acquistò un Texas Instruments TI-99. Da allora ha continuato a seguire l'evoluzione sia hardware che software avvenuta nel corso degli anni. E' un utente, un videogiocatore ed uno sviluppatore software a tempo pieno. Igor ha lavorato e lavora anche oggi con le più moderne tecnologie Microsoft per lo sviluppo di applicazioni: .NET Framework, XAML, Universal Windows Platform, su diverse piattaforme, tra cui spiccano Windows 10 piattaforme mobile. Numerose sono le app che Igor ha creato e pubblicato sul marketplace sotto il nome VivendoByte, suo personale marchio di fabbrica. Adora mantenere i contatti attraverso Twitter e soprattutto attraverso gli eventi delle community .NET.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.