2017-01-10 1 views
0

Я уже некоторое время борется с тем, как лучше всего «взаимодействовать» с настройками на уровне привязки в приложении WinRT/UWP. Я искал лучшие практики в этом отношении, но я не нашел четких ответов. В моих приложениях я сделал следующее:Рекомендации по настройке привязки к приложениям

  1. Определить BindableBase, который реализует INotifyPropertyChanged.
  2. Создание класса AppSettings, который наследуется от BindableBase и выглядит немного как это:

    public class AppSettings : BindableBase 
    { 
        ApplicationDataContainer localSettings = ApplicationData.Current.LocalSettings; 
    
        public string MySetting 
        { 
         get 
         { 
          if (!localSettings.Values.ContainsKey("MySetting")) 
           localSettings.Values["MySetting"] = "Some default value"; 
    
          return localSettings.Values["MySetting"].ToString(); 
         } 
         set 
         { 
          localSettings.Values["MySetting"] = value; 
          RaisePropertyChanged(); 
         } 
        } 
    } 
    
  3. Определить ViewModel, который имеет свойство AppSettings:

    public class SettingsViewModel 
    { 
        public AppSettings Settings { get; set; } = new AppSettings(); 
    } 
    
  4. Bind свойству Настройки в Вид:

    <TextBlock Text="{Binding Settings.MySetting, Mode=TwoWay}"> 
    

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

+1

связанный: [Зверь с лучшей практикой] (http://meta.stackexchange.com/a/142354/1228) Кроме того, вы можете использовать пояснения, что вы подразумеваете * для вступления в силу *. Вы имеете в виду спасенный немедленно? Я знаю, что в WPF нет ничего, что существовало бы в рамках, которая делает это для вас. Кажется, у вас уже есть что-то, что должно работать (ish?). Если он не делает то, что вам нужно, измените код так, чтобы он это делал. – Will

+0

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

+0

@ Будь я не так много ищут лучшей практики, но если что-то не так с моей реализацией, потому что я чувствую, что это не очень эффективная производительность. – Abdousamad

ответ

1

Это кажется прекрасным в общем случае. Единственное, что я бы изменить бы только поднять уведомление, если на самом деле изменяет данные:

set 
{ 
    if (MySetting != value) 
    { 
     localSettings.Values["MySetting"] = value; 
     RaisePropertyChanged(); 
    } 
} 

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

+0

Сохранение значений в частном поле и изменение только ApplicationData только в случае изменений, которые могут быть немного более эффективными. Что касается моей реализации RaisePropertyChanged, она уже проверяет, изменился ли параметр, если я правильно помню, но я проверю это, чтобы убедиться. – Abdousamad

0

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

public class SettingsViewModel : BindableBase 
{ 
    public string MyProperty 
    { 
     get 
     { 
      return Get("MyProperty", "SomeDefaultValue"); 
     } 
     set 
     { 
      Set("MyProperty", value); 
     } 
    } 

    public T Get<T>(string PropertyName, T DefaultValue) 
    { 
     //If setting doesn't exist, create it. 
     if (!App.Settings.ContainsKey(PropertyName)) 
      App.Settings[PropertyName] = DefaultValue; 

     return (T)App.Settings[PropertyName]; 
    } 

    public void Set<T>(string PropertyName, T Value) 
    { 
     //If setting doesn't exist or the value is different, create the setting or set new value, respectively. 
     if (!App.Settings.ContainsKey(PropertyName) || !((T)App.Settings[PropertyName]).Equals(Value)) 
     { 
      App.Settings[PropertyName] = Value; 
      OnPropertyChanged(PropertyName); 
     } 
    } 
} 

Предполагая, что ваш App класс определяет следующее свойство:

public static IPropertySet Settings 
{ 
    get 
    { 
     return Windows.Storage.ApplicationData.Current.LocalSettings.Values; 
    } 
} 

Последнее более удобно, чем писать,

ApplicationData.Current.LocalSettings.Values 

И могут быть доступны по всему миру.

Смежные вопросы