Диалог «Параметры программы» с возможностью «Сброс» - лучшие практики - PullRequest
0 голосов
/ 19 февраля 2010

Каков наилучший способ реализации диалогового окна «Параметры программы» с возможностью «Сбросить по умолчанию» в C # (версия 2005)?

Ниже описан способ, которым я занимаюсь.

  1. Создайте диалоговую форму и добавьте в нее некоторые элементы управления (например, флажки).Также добавьте три кнопки: Ok, Cancel, Default.
  2. Создать файл настроек и добавить некоторые поля в пользовательскую область.
  3. Привязать элементы управления диалогового окна к соответствующим полям настроек через «Настройки приложения»свойства в диалоговом окне свойств Visual Studio.
  4. Добавьте некоторый код в форму владельца:

    if (myDialog.ShowDialog (this) == DialogResult.OK)
    {
    MySettings.Default.Save ();
    }
    else
    {
    MySettings.Default.Reload ();
    } ​​

  5. Добавитьследующая строка в событии DefaultButtonClick в диалоговой форме:

    MySettings.Default.Reset ();

Примечание: Сохранить(), Reload (), Reset () являются общими функциями .Net класса ApplicationSettingsBase.Подробное объяснение по этому поводу можно посмотреть по адресу http://www.codeproject.com/KB/dotnet/user_settings.aspx (спасибо BillW за ссылку).

Этот код работает отлично, сохраните и восстановите пользовательские настройки без проблем, , но Функциональность «Сброс настроек по умолчанию» отличается от того, что я вижу во многих популярных программах.В моей реализации «Сброс» не может быть отменен (поскольку Settings.Default.Reset () не может быть возвращен обратно), однако, если вы видите диалоговое окно параметров какой-либо популярной программы (например, «Параметры папки» в проводнике Windows), выполните сбросможно отменить, нажав кнопку Отмена.

Итак, каков наилучший и простой способ реализации «традиционного» способа «сброса»?

Обновление (и, возможно,лучший ответ)

В настоящее время я решил проблему следующим образом.Вместо

MySettings.Default.Reset();

, который не может быть возвращен обратно, я читаю значения по умолчанию прямо так:

MySettings.Default.MyBoolValue = bool.Parse((string)MySettings.Default.Properties["MyBoolValue "].DefaultValue);

Теперь все работает так, как я хотел, но на самом деле я чувствую этокод должен быть немного грязным, потому что мне нужно сделать это для каждой переменной в отдельности, выполнить преобразование типов и так далее.Если кто-то знает лучшее простое решение, пожалуйста, напишите здесь.

Ответы [ 3 ]

2 голосов
/ 19 февраля 2010

То, что вы делаете, будет «работать», но не очень гибко.

На практике я обнаружил, что копирование значений настроек в POCO (обычный старый объект clr) работает лучше всего, при «сбросе» вы выбрасываете объект, при сохранении копируете значения обратно и сохраняете ().

Когда вы делаете привязку и т. Д., Вы привязываетесь к копии настроек. если у вас есть несколько «наборов» настроек, это помогает упорядочить вещи.

Имеет смысл? Хотя ваш план хорош; -)

1 голос
/ 15 ноября 2011

Это мой способ реализации.

[SettingsProvider(typeof(FileSettingsProvider))]
internal sealed partial class Settings: ApplicationSettingsBase {
    private static Settings defaultInstance = (Settings)ApplicationSettingsBase.Synchronized(new Settings())));
    public static Settings Default {
        get {
            return defaultInstance;
        }
    }

    public T GetDefaultValue<T>(string setting) {
        try {
            if (typeof(T) != typeof(string))
                return (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFromString((string)this.Properties[setting].DefaultValue);
            else
                return (T)this.Properties[setting].DefaultValue;
        }
        catch {
            return default(T);
        }
    }

    [UserScopedSetting()]
    [DefaultSettingValue("512")]
    public int Delay {
        get {
            return ((int)(this["Delay"]));
        }
        set {
            this["Delay"] = value;
        }
    }
}

И использование этого метода:

int d = Settings.Default.GetDefaultValue<int>("Delay");

Я создал настройки класса, потому что я хотел сохранить типы, реализованные в том же проектеи иметь возможность назначить свой собственный SettingsProvider всему классу, а не каждому свойству.Поэтому я включил метод GetDefaultValue в свой класс.Но если вы используете настройки класса, сгенерированные дизайнером, ничто не мешает использовать метод.Просто реализуйте это где-нибудь еще:

public T GetDefaultValue<T>(string setting) {
    try {
        if (typeof(T) != typeof(string))
            return (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFromString((string)Settings.Default.Properties[setting].DefaultValue);
        else
            return (T)Settings.Default.Properties[setting].DefaultValue;
    }
    catch {
        return default(T);
    }
}
0 голосов
/ 19 февраля 2010

Как упоминал @Paul Kohler, вы можете использовать DTOs . Если вы идете по этому пути, вы можете взглянуть на AutoMapper . Я не использовал его сам, но он выглядит идеально для вашей ситуации.

Другим вариантом является получение копии бизнес-объектов Expert C # 2008 от Rocky Lhotka и выполнение отмены N-уровня. Недавно коллега реализовал это на работе (на основе выпуска 2005 года), и это отлично.

...