c# form Come posso salvare/serializzare una classe personalizzata nel file delle impostazioni?



save settings file c# (4)

Ho una piccola classe che contiene due stringhe come segue:

    public class ReportType
    {
        private string displayName;
        public string DisplayName
        {
            get { return displayName; }
        }

        private string reportName;
        public string ReportName
        {
            get { return reportName; }
        }

        public ReportType(string displayName, string reportName)
        {
            this.displayName = displayName;
            this.reportName = reportName;
        }
    }

Voglio salvare un'istanza di questa classe nel mio file di impostazioni in modo che io possa fare quanto segue:

ReportType reportType = Settings.Default.SelectedReportType;

Googling sembra suggerire che è possibile, ma non sembra essere una guida chiara ovunque per me da seguire. Capisco che è necessaria qualche serializzazione ma non so davvero da dove cominciare. Inoltre, quando vado nella schermata Impostazioni in Visual Studio e faccio clic su "Sfoglia" sotto la colonna Tipo, non c'è alcuna opzione per selezionare lo spazio dei nomi corrente che contiene la classe ReportType.


Answer #1

La soluzione @Cananus non ha funzionato per me così com'è (su Visual Studio 2015). Il passo mancante è in realtà l'impostazione o ottenere dalle impostazioni effettive. Per quanto riguarda la domanda iniziale, l'implementazione di un POCO semplice può essere realizzata in questo modo:

[Serializable]
public class ReportType
{
    public string DisplayName { get; set; }
    public string ReportName { get; set; }

    public ReportType() { }

    public ReportType(string displayName, string reportName)
    {
        DisplayName = displayName;
        ReportName = reportName;
    }
}

// the class responsible for reading and writing the settings
public sealed class ReportTypeSettings : ApplicationSettingsBase
{
    [UserScopedSetting]
    [SettingsSerializeAs(SettingsSerializeAs.Xml)]
    [DefaultSettingValue("")]
    public ReportType ReportType
    {
        get { return (ReportType)this[nameof(ReportType)]; }
        set { this[nameof(ReportType)] = value; }
    }
}

Ho usato per la serializzazione in realtà un elenco:

[Serializable]
public class Schedule
{
    public Schedule() : this(string.Empty, DateTime.MaxValue)
    {
    }

    public Schedule(string path, DateTime terminationTime)
    {
        path = driverPath;
        TerminationTime = terminationTime;
    }

    public DateTime TerminationTime { get; set; }
    public string Path { get; set; }
}

public sealed class Schedules : ApplicationSettingsBase
{
    [UserScopedSetting]
    [SettingsSerializeAs(SettingsSerializeAs.Xml)]
    [DefaultSettingValue("")]
    public List<Schedule> Entries
    {
        get { return (List<Schedule>)this[nameof(Entries)]; }
        set { this[nameof(Entries)] = value; }
    }
}

Istanziare un oggetto Schedules (ReportTypeSettings). Leggerà automaticamente le impostazioni. È possibile utilizzare il metodo di ricarica per aggiornare. Per esempio:

ReportTypeSettings rts = new ReportTypeSettings();
rts.Reload();
rts.ReportType = new ReportType("report!", "report1");
rts.Save();

NOTE IMPORTANTI :

  1. Notare che UserScoped è intenzionalmente utilizzato. ApplicationScoped si comporta in modo diverso, quindi assicurati di sapere cosa stai facendo.
  2. I membri sono pubblici (incluso il setter) e c'è un lettore predefinito anche se era necessario dal codice. Tuttavia, la serializzazione tramite XML non ha funzionato correttamente. A causa di limiti di tempo, non ho indagato.
  3. Puoi anche cambiare la serializzazione in formato binario. Utilizzerà BASE64 per memorizzare i dati.
  4. Tutte le impostazioni sono memorizzate nella cartella LOCAL APP DATA, in un file di testo.

Answer #2

OK, penso che alla fine l'ho risolto. La prima cosa da fare è aggiungere i seguenti attributi a ciascuna proprietà della classe ReportType che deve essere serializzata ed ereditare la classe da ApplicationSettingsBase:

    public class ReportType : ApplicationSettingsBase
    {
        private string displayName;
        [UserScopedSetting()]
        [SettingsSerializeAs(System.Configuration.SettingsSerializeAs.Xml)]
        public string DisplayName
        {
            get { return displayName; }
        }

..............

e quindi, una volta ricostruito l'assembly (importante!), è possibile accedere alla schermata delle impostazioni e fare clic su Sfoglia, quindi digitare lo spazio dei nomi e il nome della classe nella casella di testo in basso (ad esempio Label_Creator.ReportType). Lo spazio dei nomi e il nome della classe non appaiono nell'albero e quindi questa parte non è esattamente ovvia di ciò che devi fare e questo è il motivo per cui è un po 'confuso ....


Answer #3

Che ne dici di creare un metodo statico che restituisce un'istanza di ReportType contenente dati dal file di configurazione. È più semplice e non penso che la serializzazione sia necessaria.

public class ReportType
{
  public static ReportType GetDefaultSelectedReportType()
  {
    string displayName = ConfigurationManager.AppSettings["DefaultDisplayName"];
    string reportName = ConfigurationManager.AppSettings["DefaultReportName"];
    return new ReportType(displayName, reportName);
  }
  .
  .
  .
}

Answer #4

Solo un codice un po 'più chiaro di quello di Charlie

public class ReportType
{
  public static ReportType CreateDefaults()
  {
    return new ReportType
    {
       DisplayName =  ConfigurationManager.AppSettings["DefaultDisplayName"],
       ReportName = ConfigurationManager.AppSettings["DefaultReportName"]
    };
  }
}




settings