Press "Enter" to skip to content

Common Libraries – Una classe per memorizzare informazioni sullo stato della User Interface WPF

La dimensione delle finestre è ovviamente un esempio di ciò che si può fare con questo tipo di funzionalità, un’altra potrebbe essere quella di riaprire le finestre che erano aperte nell’ultima sessione di lavoro, ripopolare i parametri di filtro su una finestra dati, ed altre cose che rendono la vita dell’utente più semplice.

Non stiamo parlando di preferenze, ma di “stato” dell’applicazione.

Da dove partiamo

Nei post Due classi per memorizzare velocemente parametri applicativi e Aggiungere alcuni parametri di configurazione ad un Servizio Windows abbiamo creato un oggetto, DnwSetting ed una collection DnwSettingsCollection che abbiamo utilizzato per gestire i parametri di configurazione applicativi del servizio windows e della sua console che stiamo costruendo.

Utilizzeremo gli stessi oggetti per memorizzare la dimensione della MainWindow della console del servizio fra un’apertura e l’altra del programma.

Modifichiamo per prima cosa il progetto DnwBaseLibraries per generare la classe base per la gestione dei parametri di stato dell’applicazione.

mini_sql_agent_06_solution_01[6]

La classe DnwAutoSettingsManagerBase

namespace Dnw.Base.Entities
{
    public abstract class DnwAutoSettingsManagerBase
    {
        protected DnwSettingsCollection mAutoSettings;
 
        public DnwSettingsCollection AutoSettings
        {
            get
            {
                if (mAutoSettings == null)
                {
                    if (File.Exists(AutoSettingsFileName))
                    {
                        mAutoSettings = DnwSettingsCollection.ReadXml(AutoSettingsFileName, false);
                    }
                    else
                    {
                        mAutoSettings = new DnwSettingsCollection();
                    }
                }
                return mAutoSettings;
            }
        }

Il manager dei parametri di stato dell’applicazione, notate che è stata definita come classe astratta, in quanto vi sono delle cose al suo interno che dipenderanno dall’applicazione che la utilizza, quindi non possiamo crearla come classe istanziabile. Abbiamo creato una collezione di DnwSetting che al primo utilizzo viene popolata leggendo un file su disco.

public abstract string AutoSettingsFileName { get; }

La property contenente il nome del file che conterrà i parametri di stato, questa dovrà ovviamente essere diversa per ogni applicazione/libreria quindi è stata definita come abstract, quindi deve essere implementata in tutte le classi derivate.

public void SetSetting(string itemID, string value)
{
    DnwSetting stt = null;
    if (!AutoSettings.Exists(itemID))
    {
        stt = new DnwSetting();
        stt.ID = itemID;
    }
    else
    {
        stt = AutoSettings[itemID];
    }
    stt.Value = value;
    AutoSettings.Add(stt);
    SaveSettings();
}

Il metodo per aggiornare un parametro di stato, che si occupa anche di aggiungerlo alla collezione se non lo trova e provvede a salvarlo immediatamente su disco.

public string GetSetting(string itemID)
{
    DnwSetting stt = AutoSettings[itemID];
    if (stt == null)
    {
        return (null);
    }
    return (stt.Value);
}

Il metodo per leggere un parametro di stato dalla collection.

private void SaveSettings()
{
    string dir = Path.GetDirectoryName(AutoSettingsFileName);
    dir.XDwCheckPath();
    AutoSettings.WriteXml(AutoSettingsFileName);
}

Il metodo per salvare su disco il contenuto della collezione dei parametri.

public void ResetSettings()
{
    mAutoSettings.Clear();
    mAutoSettings = null;
}

Un metodo di servizio, per forzare la rilettura dei parametri dal disco se necessario cancellando la collection.

Ed ora implementiamo la classe utilizzabile dall’applicazione nella nostra MiniSqlAgentConsole.

mini_sql_agent_06_solution_02[6]

La classe AutoSettingsManager

public class AutoSettingsManager : DnwAutoSettingsManagerBase
{
    private const string AUTOSTT_File = "Dnw\\MiniSqlAgent\\MiniSqlAgentConsole_AUTO.xml";

    private string mAutoSettingsFileName;

    private static AutoSettingsManager mInstance;

    private static object syncRoot = new Object();

La classe per la gestione dei parametri di stato della console del servizio, il nome del file contenente i parametri di configurazione, di solito io lo inserisco con lo stesso nome dell’exe o della dll in cui viene implementato ed un suffisso che ci indica che si tratta di parametri automatici, ma la nomenclatura è ovviamente a vostra discrezione. Abbiamo anche deciso di creare questa classe come un Singleton, in modo che sia disponibile a tutta l’applicazione automaticamente. Per essere certi di gestire correttamente anche il multithreading, abbiamo creato l’oggetto syncRoot che sarà usato per i lock durante le operazioni di lettura e scrittura.

public AutoSettingsManager()
{
    mAutoSettingsFileName = Path.Combine(Environment.GetFolderPath(
        Environment.SpecialFolder.ApplicationData),
        AUTOSTT_File);
}

Il costruttore della classe, in questo caso, quello che vi facciamo è comporre il nome del file dove sono memorizzati i parametri automatici. abbiamo utilizzato Environment.SpecialFolder.ApplicationData come cartella di destinazione perché le preferenze siano memorizzate per ciascuno degli utenti della macchina e non siano invece uguali per tutti. Ovviamente la dimensione delle finestre è solo un primo parametro che salviamo, potrebbero esservi altri parametri più interessanti da salvare in futuro che potranno essere utili se ogni utente avrà i suoi.

Nel nostro caso, la cartella così ottenuta è: C:\Users\UserName\AppData\Roaming\Dnw\MiniSqlAgent.

Che è sempre accessibile in lettura e scrittura all’utente ma solitamente è nascosta alla vista, usiamo questa cartella perché i parametri automatici usualmente non hanno la necessità di essere visti dall’utente.

public override string AutoSettingsFileName
{
    get
    {
        return (mAutoSettingsFileName);
    }
}

public static AutoSettingsManager Instance
{
    get
    {
        if (mInstance == null)
        {
            lock (syncRoot)
            {
                if (mInstance == null)
                    mInstance = new AutoSettingsManager();
            }
        }

        return mInstance;
    }
}

Le due property che espongono il nome del file dati e l’istanza della classe singleton.

Ci fermiamo qui per ora, senza testare queste due classi, perché per farlo nel prossimo post spiegheremo un concetto molto interessante, come far derivare le nostre Window da una nostra classe base invece che dalla classe Window di WPF in modo da aggiungere automaticamente funzionalità.

l codice del progetto di esempio relativo alle nuove librerie comuni è disponibile al link seguente:

Per qualsiasi domanda, approfondimento, o curiosità, utilizzate pure il link alla form di contatto in cima alla pagina o il forum Microsoft Italia su cui rispondo regolarmente.