c # – подход для сохранения пользовательских настроек в приложении WPF?

Какой подход вы рекомендуете для сохранения пользовательских настроек в приложении WPF windows (desktop)? Обратите внимание, что идея состоит в том, что пользователь может изменить свои настройки во время выполнения, а затем может закрыть приложение, а затем при запуске приложения позднее приложение будет использовать текущие настройки. Эффективно тогда он будет выглядеть так, как если бы настройки приложения не изменились.

Q1 – База данных или другой подход? У меня есть firebase database sqlite, которую я буду использовать в любом случае, поэтому использование таблицы в базе данных будет таким же хорошим, как любой подход?

Q2 – Если firebase database: какая таблица таблиц базы данных? Одна таблица со столбцами для разных типов данных, которые могут иметь (например, string , long , DateTime т. Д.) ИЛИ просто таблица со строкой для значения, на которое вы должны сериализовать и де-сериализовать значения? Я думаю, что первое было бы проще, и если не так много настроек, накладных расходов не так много?

Q3 – Можно ли использовать настройки приложения? Если да, то есть какие-то специальные задачи, необходимые для обеспечения настойчивости здесь? Также, что произойдет в отношении использования значения «по умолчанию» в дизайнере параметров приложения в этом случае? Будет ли значение по умолчанию отменять любые параметры, которые были сохранены между запуском приложения? (или вам не нужно использовать значение по умолчанию)

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

Вот несколько ссылок, в которых объясняется, как достичь этого и использовать их в WPF –

Настройки пользователя в WPF

Быстрый совет WPF: как привязать к ресурсам и настройкам приложения WPF?

Конфигурируемое окно для WPF

Вы можете сохранить ваши данные настроек как Strings XML в Settings.Default . Создайте несколько classов для хранения данных конфигурации и убедитесь, что они [Serializable] . Затем со следующими помощниками вы можете сериализовать экземпляры этих объектов – или List (или массивы T[] и т. Д.) Из них – в String . Храните каждую из этих строк в соответствующем Settings.Default в Settings.Default вашего приложения WPF.

Чтобы восстановить объекты при следующем запуске приложения, прочитайте интересующую строку Settings и Deserialize до ожидаемого типа T (который на этот раз должен быть явно указан как аргумент типа Deserialize ).

 public static String Serialize(T t) { using (StringWriter sw = new StringWriter()) using (XmlWriter xw = XmlWriter.Create(sw)) { new XmlSerializer(typeof(T)).Serialize(xw, t); return sw.GetStringBuilder().ToString(); } } public static T Deserialize(String s_xml) { using (XmlReader xw = XmlReader.Create(new StringReader(s_xml))) return (T)new XmlSerializer(typeof(T)).Deserialize(xw); } 

Я также предпочитаю сериализовать файл. Файлы XML подходят в основном для всех требований. Вы можете использовать сборку ApplicationSettings но у них есть некоторые ограничения и определенное, но (для меня) очень странное поведение, в котором они хранятся. Я использовал их много, и они работают. Но если вы хотите полностью контролировать, как и где они хранятся, я использую другой подход.

  1. Сделайте class Где-нибудь со всеми вашими настройками. Я назвал его MySettings
  2. Внедрить сохранение и чтение для сохранения
  3. Используйте их в своем коде приложения

Преимущества:

  • Очень простой подход.
  • Один class для настроек. Загрузка. Сохранить.
  • Все ваши настройки безопасны по типу.
  • Вы можете упростить или расширить логику в соответствии с вашими потребностями (Версии, много профилей на пользователя и т. Д.).
  • Он работает очень хорошо в любом случае (firebase database, WinForms, WPF, Service и т. Д.)
  • Вы можете определить, где хранить файлы XML.
  • Вы можете найти их и манипулировать ими либо с помощью кода или руководства
  • Он работает для любого метода развертывания, который я могу себе представить.

Недостатки: – Вы должны думать о том, где хранить ваши файлы настроек. (Но вы можете просто использовать свою папку для установки)

Вот простой пример (не проверенный) –

 public class MySettings { public string Setting1 { get; set; } public List Setting2 { get; set; } public void Save(string filename) { using (StreamWriter sw = new StreamWriter(filename)) { XmlSerializer xmls = new XmlSerializer(typeof(MySettings)); xmls.Serialize(sw, this); } } public MySettings Read(string filename) { using (StreamReader sw = new StreamReader(filename)) { XmlSerializer xmls = new XmlSerializer(typeof(MySettings)); return xmls.Deserialize(sw) as MySettings; } } } 

И вот как его использовать. Можно загружать значения по умолчанию или переопределять их с помощью настроек пользователя, просто проверяя, существуют ли пользовательские настройки:

 public class MyApplicationLogic { public const string UserSettingsFilename = "settings.xml"; public string _DefaultSettingspath = Assembly.GetEntryAssembly().Location + "\\Settings\\" + UserSettingsFilename; public string _UserSettingsPath = Assembly.GetEntryAssembly().Location + "\\Settings\\UserSettings\\" + UserSettingsFilename; public MyApplicationLogic() { // if default settings exist if (File.Exists(_UserSettingsPath)) this.Settings = Settings.Read(_UserSettingsPath); else this.Settings = Settings.Read(_DefaultSettingspath); } public MySettings Settings { get; private set; } public void SaveUserSettings() { Settings.Save(_UserSettingsPath); } } 

возможно, кто-то вдохновляется этим подходом. Вот как я это делаю сейчас уже много лет, и я вполне доволен этим.

Долгосрочный наиболее типичный подход к этому вопросу: Изолированное хранилище.

Сериализуйте свое состояние управления в формате XML или в другом формате (особенно легко, если вы сохраняете свойства зависимостей с помощью WPF), а затем сохраните файл в изолированном хранилище пользователя.

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

 class SettingsManager { public static void LoadSettings(FrameworkElement sender, Dictionary savedElements) { EnsureProperties(sender, savedElements); foreach (FrameworkElement element in savedElements.Keys) { try { element.SetValue(savedElements[element], Properties.Settings.Default[sender.Name + "." + element.Name]); } catch (Exception ex) { } } } public static void SaveSettings(FrameworkElement sender, Dictionary savedElements) { EnsureProperties(sender, savedElements); foreach (FrameworkElement element in savedElements.Keys) { Properties.Settings.Default[sender.Name + "." + element.Name] = element.GetValue(savedElements[element]); } Properties.Settings.Default.Save(); } public static void EnsureProperties(FrameworkElement sender, Dictionary savedElements) { foreach (FrameworkElement element in savedElements.Keys) { bool hasProperty = Properties.Settings.Default.Properties[sender.Name + "." + element.Name] != null; if (!hasProperty) { SettingsAttributeDictionary attributes = new SettingsAttributeDictionary(); UserScopedSettingAttribute attribute = new UserScopedSettingAttribute(); attributes.Add(attribute.GetType(), attribute); SettingsProperty property = new SettingsProperty(sender.Name + "." + element.Name, savedElements[element].DefaultMetadata.DefaultValue.GetType(), Properties.Settings.Default.Providers["LocalFileSettingsProvider"], false, null, SettingsSerializeAs.String, attributes, true, true); Properties.Settings.Default.Properties.Add(property); } } Properties.Settings.Default.Reload(); } } 

…..а также….

  Dictionary savedElements = new Dictionary(); public Window_Load(object sender, EventArgs e) { savedElements.Add(firstNameText, TextBox.TextProperty); savedElements.Add(lastNameText, TextBox.TextProperty); SettingsManager.LoadSettings(this, savedElements); } private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) { SettingsManager.SaveSettings(this, savedElements); } 

Помимо базы данных, вы также можете иметь следующие параметры для сохранения настроек, связанных с пользователем.

  1. реестра под HKEY_CURRENT_USER

  2. в файле в папке AppData

  3. используя файл Settings в WPF и установив его область как Пользователь

По моему опыту сохранение всех настроек в таблице базы данных является лучшим решением. Даже не беспокойтесь о производительности. Сегодняшние базы данных бывают быстрыми и могут легко хранить тысячи столбцов в таблице. Я усвоил этот трудный путь – прежде, чем я стал серилизовать / десериализовать – кошмар. Сохранение его в локальном файле или в реестре имеет одну большую проблему: если вам нужно поддерживать свое приложение, а компьютер отключен – пользователь не находится перед ним – вы ничего не можете сделать … если настройки находятся в БД – вы можете изменили их и альта, не говоря уже о том, что вы можете сравнить настройки ….

Обычно я делаю такие вещи, определяя собственный class настроек [ Serializable ] и просто сериализуя его на диск. В вашем случае вы можете просто сохранить его как строку blob в базе данных SQLite.

  1. Во всех местах, где я работал, firebase database была обязательной из-за поддержки приложений. Как сказал Адам, пользователь может быть не за своим столом, или машина может быть выключена, или вы можете быстро изменить конфигурацию кого-либо или назначить для нового участника стандартную конфигурацию (или члена команды).

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

  3. Я не использовал встроенный class настроек, поэтому я не буду комментировать. 🙂

Я хотел использовать управляющий файл xml на основе classа для моего приложения WPF для рабочего стола VB.net. Вышеприведенный код, чтобы сделать это все в одном, превосходный и поставил меня в правильном направлении. В случае, если кто-то ищет решение VB.net, вот class, который я построил:

 Imports System.IO Imports System.Xml.Serialization Public Class XControl Private _person_ID As Integer Private _person_UID As Guid 'load from file Public Function XCRead(filename As String) As XControl Using sr As StreamReader = New StreamReader(filename) Dim xmls As New XmlSerializer(GetType(XControl)) Return CType(xmls.Deserialize(sr), XControl) End Using End Function 'save to file Public Sub XCSave(filename As String) Using sw As StreamWriter = New StreamWriter(filename) Dim xmls As New XmlSerializer(GetType(XControl)) xmls.Serialize(sw, Me) End Using End Sub 'all the get/set is below here Public Property Person_ID() As Integer Get Return _person_ID End Get Set(value As Integer) _person_ID = value End Set End Property Public Property Person_UID As Guid Get Return _person_UID End Get Set(value As Guid) _person_UID = value End Set End Property End Class 
  • Android: настроить меню приложения (например, цвет фона)
  • Установка DEBUG = False вызывает ошибку 500
  • Где я должен хранить специальные настройки приложения?
  • Сообщение maven "не может найти символ" бесполезно
  • VIM Отключить автоматическую новую строку в конце файла
  • Локальные настройки Django
  • Пользовательские заголовки предпочтений
  • Команда Maven, чтобы определить, какой файл settings.xml использует Maven
  • jackson: как добавить настраиваемое свойство в JSON без изменения POJO
  • Альтернатива предпочтениям на Java
  • Поддержание общего набора предпочтений Eclipse
  • Давайте будем гением компьютера.