Как сохранить/сериализовать пользовательский класс в файл настроек?
У меня есть небольшой класс, который содержит две строки:
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;
}
}
Я хочу сохранить экземпляр этого класса в свой файл настроек, чтобы я мог сделать следующее:
ReportType reportType = Settings.Default.SelectedReportType;
Googling, похоже, предполагает, что это возможно, но, похоже, для меня не существует четкого руководства. Я понимаю, что требуется некоторая сериализация, но не знаю, с чего начать. Кроме того, когда я перехожу на экран "Настройки" в Visual Studio и "просматриваю" в столбце "Тип", нет возможности выбрать текущее пространство имен, которое содержит класс ReportType.
Ответы
Ответ 1
ОК, я думаю, что в конечном итоге я его разработал. Первое, что нужно сделать, - добавить следующие атрибуты к каждому свойству класса ReportType, который должен быть сериализован и наследовать класс из ApplicationSettingsBase:
public class ReportType : ApplicationSettingsBase
{
private string displayName;
[UserScopedSetting()]
[SettingsSerializeAs(System.Configuration.SettingsSerializeAs.Xml)]
public string DisplayName
{
get { return displayName; }
}
..............
а затем, как только вы перестроили свою сборку (важно!), вы можете перейти на экран настроек и нажать кнопку "Обзор", а затем введите свое пространство имен и имя класса в текстовое поле внизу (например, Label_Creator.ReportType). Пространство имен и имя класса не отображаются в дереве, и поэтому эта часть не совсем очевидна, что вам нужно сделать, поэтому она немного запутанна....
Ответ 2
Как создать статический метод, который возвращает экземпляр типа ReportType, содержащий данные из файла конфигурации. Это проще, и я не думаю, что сериализация необходима.
public class ReportType
{
public static ReportType GetDefaultSelectedReportType()
{
string displayName = ConfigurationManager.AppSettings["DefaultDisplayName"];
string reportName = ConfigurationManager.AppSettings["DefaultReportName"];
return new ReportType(displayName, reportName);
}
.
.
.
}
Ответ 3
Немного более четкий код, затем Charlie's
public class ReportType
{
public static ReportType CreateDefaults()
{
return new ReportType
{
DisplayName = ConfigurationManager.AppSettings["DefaultDisplayName"],
ReportName = ConfigurationManager.AppSettings["DefaultReportName"]
};
}
}
Ответ 4
Решение @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; }
}
}
Я использовал для фактической сериализации список:
[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; }
}
}
Создайте экземпляр объекта Schedules (ReportTypeSettings). Он автоматически прочитает настройки. Вы можете использовать метод Reload для обновления.
Например:
ReportTypeSettings rts = new ReportTypeSettings();
rts.Reload();
rts.ReportType = new ReportType("report!", "report1");
rts.Save();
ВАЖНЫЕ ПРИМЕЧАНИЯ:
- Обратите внимание, что UserScoped намеренно используется. ApplicationScoped ведет себя по-другому, поэтому убедитесь, что вы знаете, что делаете.
- Члены являются общедоступными (включая setter), и там используется c'tor по умолчанию, даже если это необходимо для кода. Однако сериализация с использованием XML не работала должным образом. Из-за ограничений по времени я не исследовал.
- Вы также можете изменить сериализацию в двоичном формате. Он будет использовать BASE64 для хранения данных.
- Все настройки сохраняются в папке LOCAL APP DATA в текстовом файле.