Как сохранить / сериализовать пользовательский класс в файл настроек? - PullRequest
18 голосов
/ 24 августа 2009

У меня есть небольшой класс, который содержит две строки следующим образом:

    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;

Похоже, поиск в Google предполагает, что это возможно, но, похоже, нигде нет четкого руководства, которому я мог бы следовать. Я понимаю, что требуется некоторая сериализация, но не знаю, с чего начать. Кроме того, когда я захожу на экран «Настройки» в Visual Studio и нажимаю «Обзор» в столбце «Тип», невозможно выбрать текущее пространство имен, содержащее класс ReportType.

Ответы [ 4 ]

18 голосов
/ 24 августа 2009

Хорошо, я думаю, что в конце концов все уладил. Первое, что нужно сделать, это добавить следующие атрибуты в каждое свойство класса ReportType, которое необходимо сериализовать, и наследовать класс от ApplicationSettingsBase:

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

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

и затем, как только вы восстановите свою сборку (важно!), Вы можете перейти на экран настроек и нажать кнопку обзора, а затем ввести свое пространство имен и имя класса в текстовое поле внизу (например, Label_Creator.ReportType). Пространство имен и имя класса не появляются в дереве, и поэтому эта часть не совсем очевидна, что вам нужно сделать, поэтому она немного сбивает с толку ....

3 голосов
/ 21 мая 2016

@ Решение 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). Он автоматически прочитает настройки. Вы можете использовать метод перезагрузки для обновления. Например:

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

ВАЖНЫЕ ЗАМЕЧАНИЯ :

  1. Обратите внимание, что UserScoped намеренно используется. ApplicationScoped ведет себя по-разному, поэтому убедитесь, что вы знаете, что делаете.
  2. Члены являются общедоступными (включая установщик), и по умолчанию существует c'or, даже если это было необходимо для кода. Однако сериализация с использованием XML не сработала должным образом. Из-за нехватки времени я не расследовал.
  3. Вы также можете изменить сериализацию на двоичный формат. Для хранения данных будет использоваться BASE64.
  4. Все настройки хранятся в папке LOCAL APP DATA, в текстовом файле.
2 голосов
/ 24 августа 2009

Чуть более понятный код, чем Чарли

public class ReportType
{
  public static ReportType CreateDefaults()
  {
    return new ReportType
    {
       DisplayName =  ConfigurationManager.AppSettings["DefaultDisplayName"],
       ReportName = ConfigurationManager.AppSettings["DefaultReportName"]
    };
  }
}
2 голосов
/ 24 августа 2009

Как насчет создания статического метода, который возвращает экземпляр ReportType, содержащий данные из файла конфигурации. Это проще, и я не думаю, что сериализация необходима.

public class ReportType
{
  public static ReportType GetDefaultSelectedReportType()
  {
    string displayName = ConfigurationManager.AppSettings["DefaultDisplayName"];
    string reportName = ConfigurationManager.AppSettings["DefaultReportName"];
    return new ReportType(displayName, reportName);
  }
  .
  .
  .
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...