Рекомендации по хранению настроек пользовательского интерфейса?

В настоящее время мы планируем большее приложение WPF LoB, и мне интересно, что другие считают лучшей практикой для хранения множества настроек пользовательского интерфейса, например.

  • Расширительные состояния
  • Заказы меню
  • Свойства калибровки
  • и т.д...

Мне не нравится идея иметь десятки сохраненных значений, используя поставляемый файл SettingsProvider (т.е. файл App.config), хотя его можно использовать для его хранения во встроенной базе данных с помощью настраиваемого параметра SettingsProvider. возможность использования своего рода привязки данных также вызывает беспокойство. У кого-то были те же проблемы?

Что вы сделали, чтобы сохранить множество пользовательских настроек ui?

Ответ 1

Здесь мы сохраняем файл настроек:

Environment.SpecialFolder.ApplicationData

Сохраните его как файл xml "preferences", поэтому его не так сложно найти и изменить, если он когда-либо поврежден.

До сих пор это работало намного лучше, чем реестр для нас, он чище и проще выдувать, если что-то повреждено или должно быть reset.

Ответ 2

Более быстрый способ сохранения настроек пользовательского интерфейса - использовать систему Properties.Settings.Default. Что может быть хорошо с ним, так это использовать привязку WPF к значению. Пример здесь. Settins автоматически обновляются и загружаются.

<Window ...
    xmlns:p="clr-namespace:UserSettings.Properties"
    Height="{Binding Source={x:Static p:Settings.Default}, Path=Height, Mode=TwoWay}" 
    Width="{Binding Source={x:Static p:Settings.Default}, Path=Width, Mode=TwoWay}" 
    Left="{Binding Source={x:Static p:Settings.Default}, Path=Left, Mode=TwoWay}" 
    Top="{Binding Source={x:Static p:Settings.Default}, Path=Top, Mode=TwoWay}">

...
protected override void OnClosing(System.ComponentModel.CancelEventArgs e) 
{ 
    Settings.Default.Save(); 
    base.OnClosing(e); 
}

Проблема в том, что он быстро становится беспорядком, если ваше приложение велико.

Другим решением (предложенным кем-то здесь) является использование пути ApplicationData для хранения ваших собственных предпочтений в XML. Там вы можете создать свой собственный класс уставок и использовать XML-сериализатор для его сохранения. Этот подход позволяет выполнить переход с версий на версии. Будучи более мощным, этот метод требует немного больше кода.

Ответ 3

Копаясь в ответе aogan и комбинируя его с ответом decasteljau и сообщением в блоге, на которое он ссылается, вот пример, который заполняет некоторые пробелы, которые мне не были понятны.

Файл xaml:

<Window ...
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:p="clr-namespace:MyApp"
    Height="{Binding Source={x:Static p:MyAppSettings.Default}, Path=MainWndHeight, Mode=TwoWay}"
    Width="{Binding Source={x:Static p:MyAppSettings.Default}, Path=MainWndWidth, Mode=TwoWay}"
    Left="{Binding Source={x:Static p:MyAppSettings.Default}, Path=MainWndLeft, Mode=TwoWay}"
    Top="{Binding Source={x:Static p:MyAppSettings.Default}, Path=MainWndTop, Mode=TwoWay}"
    ...

И исходный файл:

namespace MyApp
{
    class MainWindow ....
    {
        ...

        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            MyAppSettings.Default.Save();
            base.OnClosing(e);
        }
    }

    public sealed class MyAppSettings : System.Configuration.ApplicationSettingsBase
    {
        private static MyAppSettings defaultInstance = ((MyAppSettings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new MyAppSettings())));
        public static MyAppSettings Default
        {
            get { return defaultInstance; }
        }

        [System.Configuration.UserScopedSettingAttribute()]
        [System.Configuration.DefaultSettingValueAttribute("540")]
        public int MainWndHeight
        {
            get { return (int)this["MainWndHeight"]; }
            set { this["MainWndHeight"] = value; }
        }

        [System.Configuration.UserScopedSettingAttribute()]
        [System.Configuration.DefaultSettingValueAttribute("790")]
        public int MainWndWidth
        {
            get { return (int)this["MainWndWidth"]; }
            set { this["MainWndWidth"] = value; }
        }

        [System.Configuration.UserScopedSettingAttribute()]
        [System.Configuration.DefaultSettingValueAttribute("300")]
        public int MainWndTop
        {
            get { return (int)this["MainWndTop"]; }
            set { this["MainWndTop"] = value; }
        }

        [System.Configuration.UserScopedSettingAttribute()]
        [System.Configuration.DefaultSettingValueAttribute("300")]
        public int MainWndLeft
        {
            get { return (int)this["MainWndLeft"]; }
            set { this["MainWndLeft"] = value; }
        }
    }
}

Ответ 4

Мы сохраняем все в Isolation Storage (мы работаем с ClickOnce). У нас есть некоторый объект, который мы сериализуем (XmlSerializer).

Ответ 5

Кажется, по какой-то причине теряется популярность; но реестр всегда был подходящим местом для этих настроек.

Ответ 6

Мы используем настраиваемый SettingsProvider для хранения информации о конфигурации в таблице в базе данных приложения. Это хорошее решение, если вы уже используете базу данных.

Ответ 7

В Программировании WPF Крисом Продавсом и Ян Гриффитсом говорится:

Предпочтительным механизмом настройки для приложения WPF является тот, который предоставляется .NET и VS: класс ApplicationSettingBase из пространства имен System.Configuration со встроенным конструктором.