+ Rispondi al Thread
Pagina 1 di 2 12 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 16

Discussione: [.NET 4.6.1] Persistenza di Setting create a Runtime

  1. #1
    Sgrubak non è in linea Scolaretto
    Luogo
    Torrazza Piemonte
    Post
    323

    [.NET 4.6.1] Persistenza di Setting create a Runtime

    Buongiorno a tutti,
    più per motivo di studio degli Extention Methods, e anche per una buona dose di pigrizia, stavo cercando di trovare una maniera facile e veloce per memorizzare le proprietà Location e WindowState di una form qualunque tra le impostazioni dell'applicazione, senza dover necessariamente inserire a meno dette proprietà.

    Una ricerca in rete mi ha portato a scrivere i seguente codice:
    codice:
        public static class FormExtentions
        {
            public static void SalvaProprietaForm(this Form form)
            {
                //Prelevo il nome de Tipo di Form
                string nomeTipoForm = form.GetType().Name;
                string nomeProprieta = nomeTipoForm + "Location";
                try
                {
                    //Provo a scrivere il valore nella proprietà. Nel caso non esista solleva eccezione
                    Properties.Settings.Default[nomeProprieta] = form.Location;
                }
                catch (Exception ex)
                {
                    //Gestisco l'eventuale sollevamento dell'eccezione creando una nuova proprietà e poi assegnandole il valore
                    CreaNuovaProprieta(nomeProprieta, typeof(Point));
                    Properties.Settings.Default[nomeProprieta] = form.Location;
                }
    
                try
                {
                    nomeProprieta = nomeTipoForm + "WindowsState";
                    Properties.Settings.Default[nomeProprieta] = form.WindowState;
                }
                catch (Exception ex)
                {
                    CreaNuovaProprieta(nomeProprieta, typeof(FormWindowState));
                    Properties.Settings.Default[nomeProprieta] = form.WindowState;
                }
                Properties.Settings.Default.Save();
            }
            public static void CaricaProprietaForm(this Form form)
            {
                string nomeTipoForm = form.GetType().Name;
                string nomeProprieta = nomeTipoForm + "Location";
                try
                {
                    form.Location = (Point)Properties.Settings.Default[nomeProprieta];
                }
                catch (Exception ex) { }
                nomeProprieta = nomeTipoForm + "WindowsState";
                try
                {
                    form.WindowState = (FormWindowState)Properties.Settings.Default[nomeProprieta];
                }
                catch (Exception ex) { }
            }
            private static void CreaNuovaProprieta(string nomeProprieta, Type tipoProprieta)
            {
                SettingsProperty property = new SettingsProperty(nomeProprieta);
                property.IsReadOnly = false;
                property.PropertyType = tipoProprieta;
                property.Provider = Properties.Settings.Default.Providers["LocalFileSettingsProvider"];
                property.Attributes.Add(typeof(UserScopedSettingAttribute), new UserScopedSettingAttribute());
                Properties.Settings.Default.Properties.Add(property);
                Properties.Settings.Default.Save();
                // Ricarico le proprietà
    
                Properties.Settings.Default.Reload();
            }
        }
    Sfrutto questi metodi di estensione nella gestione degli eventi Load (this.CaricaProprietaForm) e nell'evento FormClosing (this.SalvaPropietaForm).

    Il tutto funziona a dovere, se non per il fatto che la persistenza regge, ma soltanto all'interno di una stessa sessione di lavoro. Alla chiusura dell'applicazione, queste proprietà spariscono e devo riposizionare tutte le form ogni volta.

    Ovviamente se procedo con il metodo canonico di aggiungere le proprietà manualmente e di salvare/caricare i valori, la persistenza c'è anche tra sessioni lavorative diverse.

    Sapete suggerirmi cosa manca?

    Grazie in anticipo.

  2. #2
    L'avatar di _alka_
    _alka_ non è in linea Very Important Person
    Luogo
    Reggio Emilia
    Post
    1,158
    Cosa intendi quandi dici procedo con il metodo canonico?
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Homepage | Blog | Delphi Podcast | Delphi Succinctly (e-book)

  3. #3
    Sgrubak non è in linea Scolaretto
    Luogo
    Torrazza Piemonte
    Post
    323
    Inserisco la proprietà manualmente, e poi accedo al valore tramite [Settings.Default.NomeProprieta].

  4. #4
    L'avatar di _alka_
    _alka_ non è in linea Very Important Person
    Luogo
    Reggio Emilia
    Post
    1,158
    Hai provato a vedere se lanciando esternamente l'applicazione (fuori dall'IDE di VS e senza debug) ottieni lo stesso effetto?

    Non vorrei che l'applicazione venisse "ospitata" in qualche eseguibile host esterno e quindi le impostazioni legate a un processo che poi viene rigenerato, magari con un nome diverso.
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Homepage | Blog | Delphi Podcast | Delphi Succinctly (e-book)

  5. #5
    Sgrubak non è in linea Scolaretto
    Luogo
    Torrazza Piemonte
    Post
    323
    Quote Originariamente inviato da _alka_ Visualizza il messaggio
    Hai provato a vedere se lanciando esternamente l'applicazione (fuori dall'IDE di VS e senza debug) ottieni lo stesso effetto?...
    Sperando di aver compreso il tuo suggerimento, ho tentato queste due strade:

    1) Compilare in Release e lanciare l'exe dal percorso bin/Release nella cartella del progetto.
    2) Pubblicare l'applicazione in un percorso di rete e installarla sul client, poi lanciarla come una normale applicazione

    In nessuno dei due casi ho raggiunto l'obiettivo. Le finestre si riaprono nella posizione in cui le ho chiuse, solo se non chiudo l'applicazione. Fintanto che la form di avvio resta aperta, le proprietà create a runtime vengono correttamente gestite.
    Potrebbe esistere un metodo da invocare in chiusura dell'applicazione? Io però su docs.microsoft.com non ho trovato nulla al riguardo.

  6. #6
    L'avatar di _alka_
    _alka_ non è in linea Very Important Person
    Luogo
    Reggio Emilia
    Post
    1,158
    Quote Originariamente inviato da Sgrubak Visualizza il messaggio
    Sperando di aver compreso il tuo suggerimento, ho tentato queste due strade: [...]
    In nessuno dei due casi ho raggiunto l'obiettivo.
    Non è che forse è il caso di pubblicare qualche altro pezzo di codice?
    Ad esempio, l'invocazione dei metodi nel Form, oppure qualche altro dettaglio implementativo sulle "famigerate finestre".
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Homepage | Blog | Delphi Podcast | Delphi Succinctly (e-book)

  7. #7
    Sgrubak non è in linea Scolaretto
    Luogo
    Torrazza Piemonte
    Post
    323
    Quote Originariamente inviato da _alka_ Visualizza il messaggio
    Non è che forse è il caso di pubblicare qualche altro pezzo di codice?...
    Ecco come invoco gli extention methods nelle varie classi:
    codice:
    public partial class FrmProg : Form
    {
    //Altro codice della classe...
            private void FrmProg_Load(object sender, EventArgs e)
            {
                //this.CaricaProprietaForm();
                Location = Settings.Default.frmProgLocation;
                WindowState = Settings.Default.frmProgWindowState;
            }
            private void FrmProg_FormClosing(object sender, FormClosingEventArgs e)
            {
                //this.SalvaProprietaForm();
                Settings.Default.frmProgLocation = Location;
                Settings.Default.frmProgWindowState = WindowState;
                Settings.Default.Save();
            }
    
    }
    In questo caso specifico le chiamate sono commentate. Le proprietà [frmProgLocation] e [frmProgWindowState] le ho create io manualmente. Riesco a leggerne e scriverne i valori sia con le istruzioni sopra riportate che con le chiamate ai metodi al momento commentate. Ovviamente se utilizzo questo sistema, i valori persistono anche tra sessioni di lavoro diverse.

    In tutte le altre form il codice si presenta semplicemente così:
    codice:
    public partial class FrmDettaglioArticolo : Form
    {
            private void frmDettaglioArticolo_Load(object sender, EventArgs e)
            {
                this.CaricaProprietaForm();
            }
            private void FrmDettaglioArticolo_FormClosing(object sender, FormClosingEventArgs e)
            {
                this.SalvaProprietaForm();
            }
    }
    Questo codice funziona solo all'interno di una stessa sessione di lavoro. Quindi nel momento in cui apro la prima volta una finestra di tipo [FrmDettaglioArticolo] la Location e il WindowState sono quelli di default. Quando la sposto e/o ridimensiono e poi la chiudo, alla seconda apertura carica il Point e il FormWindowState che valevano alla chiusura. Lo stesso comportamento lo ottengo con tipi di form diversi (ne ho circa una decina di form nel progetto e mi appresto ad aggiungerne altre, per questo cercavo un metodo che potesse applicarsi a tutte indistintamente).

    Ovviamente i gestori degli eventi sono correttamente impostati in modalità di progettazione.

  8. #8
    Ferrari_and non è in linea Scolaretto
    Post
    138
    Il comportamento che sta illustrando è normale in quanto le informazioni che stai gestendo sono contenute in memoria.
    Quindi quando chiudi l'applicativo la memoria viene liberata quindi perse le informazioni.
    Esiste la possibilità di memorizzare queste informazioni in un file con il metodo

    Properties.Settings.Default.Save();

    Il metodo server per mantenere le modifiche alle impostazioni tra sessioni dell'applicazione.
    Le impostazioni utente vengono salvate in un file all'interno di una sottocartella della cartella dati applicazioni nascosta locale dell'utente.

    Penso che sia un possibile metodo per storicizzare i settaggi altrimenti devi gestire tu un file in cui inserirli alla chiusura per poi ripecarli
    . [vedi il metodo Reload se esiste e come funziona]

    Se trovi come fare facci sapere grazie
    Ultima modifica di Ferrari_and; 26-07-2019 09:41 

  9. #9
    Sgrubak non è in linea Scolaretto
    Luogo
    Torrazza Piemonte
    Post
    323
    Grazie Ferrari_and. Entrambe le istruzioni che mi hai suggerito le conoscevo e sono state opportunamente integrate nel codice che ho riportato nel post di apertura. La mia domanda nasce proprio dal fatto che, nonostante io salvi e ricarichi le impostazioni. queste persistano fino alla chiusura e poi più niente.

  10. #10
    Ferrari_and non è in linea Scolaretto
    Post
    138
    Scusa non avevo letto il codice

    Unica cosa che ho notato da vecchio programmatore VB6 è che negli spezzoni di codice prima fai il save e poi il reload.
    Domanda hai fatto un reload ad aperture programma per caricare le configurazioni l'ipotesi è che partendo con un default vuoto venga distrutto il file di configurazione che contiene le variabili per crearne uno nuovo vuoto.

+ Rispondi al Thread
Pagina 1 di 2 12 ultimoultimo

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi