+ Rispondi al Thread
Pagina 2 di 2 primaprima 12
Visualizzazione dei risultati da 11 a 16 su 16

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

  1. #11
    Sgrubak non è in linea Scolaretto
    Luogo
    Torrazza Piemonte
    Post
    286
    È un'ipotesi interessante ma che tenderei a scartare. Se distruggesse e ricreasse il file ad ogni chiusura/riapertura dell'applicazione, dovrebbe ripartire dai valori iniziali anche per le impostazioni che ho creato manualmente. Ma così non è... Quelle persistono tra un lancio e l'altro grazie al metodo Save(). Quelle che creo io a runtime spariscono e vengono ricreate nel blocco catch.

  2. #12
    Ferrari_and non è in linea Scolaretto
    Post
    108
    Prova a controllare il file / registro che crea il metodo Save per vedere se ci sono anche quelle create a runtime quando chiudi il programma.
    Nel caso non le trovi è un problema della creazione della nuova variabile. Nel caso ci siano è un problema di inizializzazione della lista dei parametri di default che viene letta non dal file.

  3. #13
    Sgrubak non è in linea Scolaretto
    Luogo
    Torrazza Piemonte
    Post
    286
    Quote Originariamente inviato da Ferrari_and Visualizza il messaggio
    Prova a controllare il file / registro che crea il metodo Save per vedere se ci sono anche quelle create a runtime quando chiudi il programma.
    Ho controllato e non le trovo. Ho provato quindi a seguire un differente approccio, tentando di editare direttamente il file modificando la funzione [CreaNuovaProprieta]
    codice:
            private static void CreaNuovaProprieta(string nomeProprieta, Type tipoProprieta)
            {
                //Parte vecchia: non funziona se chiudo/riapro l'applicazione
                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();
    
                //Parte nuova
                Configuration config = ConfigurationManager.OpenExeConfiguration(Application.ExecutablePath);
                ConfigurationSectionGroup sectionGroup = config.SectionGroups["userSettings"];
                ClientSettingsSection impostazioni = (ClientSettingsSection)sectionGroup.Sections["ProgramCSharp.Properties.Settings"];
                SettingElement nuovoElemento = new SettingElement(property.Name, property.SerializeAs);
                impostazioni.Settings.Add(nuovoElemento);
                config.Save(ConfigurationSaveMode.Modified);
            }
    Così facendo, la proprietà viene aggiunta al file, ma senza il nodo <value>:
    codice:
    <setting name="frmCambioMacchinaLocation" serializeAs="String">
          <value>100, 100</value>
    </setting>
    <setting name="nuovaproprieta" serializeAs="String"/>
    Ergo in fase di scrittura del valore della proprietà solleva l'eccezione System.Configuration.ConfigurationErrorsException: 'Attributo obbligatorio 'value' non trovato.
    Non riesco a trovare la maniera fargli aggiungere il nodo più interno...

  4. #14
    L'avatar di _alka_
    _alka_ non è in linea Very Important Person
    Luogo
    Reggio Emilia
    Post
    1,152
    Quote Originariamente inviato da Sgrubak Visualizza il messaggio
    Non riesco a trovare la maniera fargli aggiungere il nodo più interno...
    Ho il sospetto che le impostazioni di cui si parla, create a runtime, debbano andare a finire nel file .config dell'applicazione, che generalmente però si trova nella stessa cartella dell'eseguibile, quindi le voci già configurate non hanno problemi, mentre quelle create "al volo" sì perché non sono anticipatamente dichiarate e supportate dal meccanismo dei setting, che si aspetta di trovarle in fase di inizializzazione del sistema.

    Considerando il punto in cui sei arrivato, la soluzione inizia a sembrarmi già fin troppo complessa per un'esigenza simile, quando basterebbe ricavare la directory del profilo dell'utente e magari salvare, serializzando in XML o in JSON, delle semplici proprietà con i rispettivi valori, andandoli poi a caricare/salvare quando necessario, dato che il codice di impostazione delle singole proprietà alla fine devi scriverlo ugualmente.

    A meno che non sia per un esercizio di stile o per "risoluzione del mistero", io adotterei un mezzo differente (come quello suggerito qui sopra) e abbandonerei la strada dei Setting, se non altro per il tipo di utilizzo che ne stai facendo, ossia crearli dinamicamente.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

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

  5. #15
    Sgrubak non è in linea Scolaretto
    Luogo
    Torrazza Piemonte
    Post
    286
    Grazie Marco,
    ho provato a rintracciare il file .config nella cartella dell'eseguibile e di fatto esiste ed è un file XML. "Niente di più facile!" mi sono detto... Ma ho parlato troppo presto.
    codice:
    XmlNode configuration = config.SelectSingleNode("configuration");
    XmlNode userSettings = configuration.SelectSingleNode("userSettings");
    XmlNode settings = userSettings.SelectSingleNode(Application.ProductName + " .Properties.Settings");
    //creo la nuova proprietà in XML
    XmlNode proprieta = config.CreateElement("setting");
    XmlAttribute name = config.CreateAttribute("name");
    name.Value = property.Name;
    XmlAttribute serializeAs = config.CreateAttribute("serializeAs");
    serializeAs.Value = property.SerializeAs.ToString();
    proprieta.Attributes.Append(name);
    proprieta.Attributes.Append(serializeAs);
    XmlNode value = config.CreateElement("value");
    proprieta.AppendChild(value);
    //aggiungo il nodo
    settings.AppendChild(proprieta);
    Tutto corretto sintatticamente e a livello logico, peccato che, pur esistendo il nodo <userSettings> nel file (ho verificato aprendolo con NotePad++) non esiste nel XmlNode [configuration].

    Probabilmente le nasconde per proteggere quella sezione che, deduzione mia arrivato a questo punto, non DEVE essere modificata a runtime.

    Sfrutterò il tuo suggerimento e tenterò un'altra strada.

    P.S: Questo il file XML:
    codice:
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <configSections>
        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
          <section name="ProgramCSharp.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
        </sectionGroup>
      </configSections>
      <connectionStrings>
        <add name="ProgramCSharp.Properties.Settings.ProgrammatoreConnectionString"
            connectionString="Data Source=(LocalDb)\MSSQLLocalDB;Initial Catalog=Programmatore;Integrated Security=True"
            providerName="System.Data.SqlClient" />
        <add name="ProgramCSharp.Properties.Settings.ArcaConnectionString"
            connectionString="Data Source=SERVER2;Initial Catalog=ADB_STAR2014;Integrated Security=True"
            providerName="System.Data.SqlClient" />
      </connectionStrings>
      <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
      </startup>
      <userSettings>
        <ProgramCSharp.Properties.Settings>
          <setting name="SecondiOra" serializeAs="String">
            <value>2600</value>
          </setting>
          <setting name="frmProgLocation" serializeAs="String">
            <value>0, 0</value>
          </setting>
          <setting name="frmProgWindowState" serializeAs="String">
            <value>Maximized</value>
          </setting>
          <setting name="frmCambioMacchinaLocation" serializeAs="String">
            <value>100, 100</value>
          </setting>
        </ProgramCSharp.Properties.Settings>
      </userSettings>
    </configuration>

  6. #16
    L'avatar di _alka_
    _alka_ non è in linea Very Important Person
    Luogo
    Reggio Emilia
    Post
    1,152
    Quote Originariamente inviato da Sgrubak Visualizza il messaggio
    Probabilmente le nasconde per proteggere quella sezione che, deduzione mia arrivato a questo punto, non DEVE essere modificata a runtime.
    Il file .config non è fatto per essere modificato a runtime, anche perché di solito viene posto nella directory assieme al programma, dove generalmente non si hanno nemmeno i diritti di scrittura (senza acquisire i diritti amministrativi tramite UAC).

    Non è nemmeno comunque consigliato modificarlo a mano, motivo per cui non sono presenti classi nel framework adatte a questo scopo.

    Valuterei davvero una strada più consona.
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

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

+ Rispondi al Thread
Pagina 2 di 2 primaprima 12

Permessi di invio

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