如何将自定义类保存/序列化到设置文件?

Cal*_*nus 19 c# settings visual-studio

我有一个小类,它包含两个字符串,如下所示:

    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;
        }
    }
Run Code Online (Sandbox Code Playgroud)

我想将此类的实例保存到我的设置文件中,以便我可以执行以下操作:

ReportType reportType = Settings.Default.SelectedReportType;
Run Code Online (Sandbox Code Playgroud)

谷歌搜索似乎表明它是可能的,但似乎没有任何明确的指南可供我遵循.我知道有些序列化是必需的,但不知道从哪里开始.此外,当我进入Visual Studio的"设置"屏幕并单击"类型"列下的"浏览"时,没有选项可以选择包含ReportType类的当前命名空间.

Cal*_*nus 18

好吧,我认为我最终解决了这个问题.要做的第一件事是将以下属性添加到需要序列化的ReportType类的每个属性,并从ApplicationSettingsBase继承该类:

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

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

然后,一旦重建了程序集(重要!),您可以进入设置屏幕并单击浏览,然后在底部的文本框中键入您的命名空间和类名(例如Label_Creator.ReportType).命名空间和类名不会出现在树中,所以这部分并不是很明显你需要做什么,这就是为什么它有点令人困惑....

  • 那你如何初始化这个属性呢?我试图重现你的步骤,但它一直在失败.当我调用(使用你的情况)Settings.Default.ReportType时,它会丢弃一个空引用异常...问题可能是我的属性使用winforms Keys类而不是例如string (2认同)
  • 这个解决方案对我不起作用,不确定是否是由于发布时存在 VS 版本所致。为了其他人的利益,我提出另一个答案。 (2认同)

Guy*_*Guy 5

@Calanus 解决方案对我来说并不适用(在 Visual Studio 2015 上)。缺少的步骤实际上是设置或从实际设置中获取。至于原来的问题,实现一个简单的 POCO 可以这样实现:

[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; }
    }
}
Run Code Online (Sandbox Code Playgroud)

我已经用于实际序列化列表:

[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; }
    }
}
Run Code Online (Sandbox Code Playgroud)

实例化一个 Schedules (ReportTypeSettings) 对象。它会自动读取设置。您可以使用 Reload 方法进行刷新。例如:

ReportTypeSettings rts = new ReportTypeSettings();
rts.Reload();
rts.ReportType = new ReportType("report!", "report1");
rts.Save();
Run Code Online (Sandbox Code Playgroud)

重要说明

  1. 请注意,UserScoped 是有意使用的。ApplicationScoped 的行为有所不同,因此请确保您知道自己在做什么。
  2. 成员是公共的(包括 setter),并且即使代码需要它,也有一个默认构造函数。但是,使用 XML 的序列化无法正常工作。由于时间关系,我没有去研究。
  3. 您也可以将序列化更改为二进制格式。它将使用 BASE64 来存储数据。
  4. 所有设置都存储在 LOCAL APP DATA 文件夹中的文本文件中。