Рекомендации по хранению настроек пользовательского интерфейса?
В настоящее время мы планируем большее приложение 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 со встроенным конструктором.