2015-10-06 4 views
0

Я был по-настоящему большие настройки Xamarin Cross Platform плагин https://components.xamarin.com/view/SettingsPlugin (версия NuGet этого в PCL, чтобы быть точным)Xamarin Формы Настройки Plugin Bindable

Он хорошо работает, но теперь с помощью Xamarin формы я действительно нравится уметь привязывать значения настроек. Я хотел бы иметь метку на странице содержимого, которая гласит: «Значение настройки: [значение]» и обновляется при изменении настройки.

Настройки по классу выглядит следующим образом:

public static class Settings { 

    private static ISettings AppSettings 
{ 
    get 
    { 
    return CrossSettings.Current; 
    } 
} 

#region Setting Constants 

    const string HOT_TIME_COUNT_KEY = "hotTimeCount"; 
    private static readonly int HOT_TIME_COUNT_DEFAULT = 0; 



    #endregion 



    public static int HotTimeCount 
    { 
     get { return AppSettings.GetValueOrDefault(HOT_TIME_COUNT_KEY, HOT_TIME_COUNT_DEFAULT); } 
     set { AppSettings.AddOrUpdateValue(HOT_TIME_COUNT_KEY, value); } 
    } 

}

Я просто не могу показаться, чтобы выяснить, что формат требуется, чтобы сделать эту работу? BindableProperty.Create? Нужен ли метод OnPropertyChanged? Нужен ли класс настроек из BindableObject?

ответ

1

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

public class MyViewModel : INotifyPropertyChanged 
{ 

    public int Time 
    { 
     get { return Settings.HotTimeCount; } 
     set 
     { 
      if (Settings.HotTimeCount == value) 
       return; 

      Settings.HotTimeCount = value; 
      OnPropertyChanged(); 
     } 

    } 

    private Command increase; 
    public Command IncreaseCommand 
    { 
     get 
     { 
      return increase ?? (increase = new Command(() =>Time++)); 
     } 
    } 

    #region INotifyPropertyChanged implementation 

    public event PropertyChangedEventHandler PropertyChanged; 

    public void OnPropertyChanged([CallerMemberName]string name = "") 
    { 
     var changed = PropertyChanged; 
     if (changed == null) 
      return; 
     changed(this, new PropertyChangedEventArgs(name)); 
    } 

    #endregion 


} 

Затем XAML будет выглядеть внутри вашей страницы Содержание:

<StackLayout Padding="25"> 

<Button Text="Increase" Command="{Binding IncreaseCommand}"/> 
<Label Text="{Binding Time, StringFormat='The time is {0:F0}'}"/> 

</StackLayout> 

Убедитесь, что вы установите BindingContext в xaml.cs страницы:

public partial class MyPage : ContentPage 
{ 
    public MyPage() 
    { 
     InitializeComponent(); 
     BindingContext = new MyViewModel(); 
    } 
} 

Это на самом деле не слишком много кода на самом деле осуществить, как ваш ViewModel будет иметь BaseViewModel, реализующий INotifyProprety изменилось, s о действительно вы просто добавить в

public int Time 
    { 
     get { return Settings.HotTimeCount; } 
     set 
     { 
      if (Settings.HotTimeCount == value) 
       return; 

      Settings.HotTimeCount = value; 
      OnPropertyChanged(); 
     } 

    } 

Более магическим образом

Однако, используя полномочия C# и зная, как Databinding работы вы могли бы сначала создать BaseViewModel, что все будет использовать:

public class BaseViewModel : INotifyPropertyChanged 
{ 

    public Settings Settings 
    { 
     get { return Settings.Current; } 
    } 


    #region INotifyPropertyChanged implementation 

    public event PropertyChangedEventHandler PropertyChanged; 

    public void OnPropertyChanged([CallerMemberName]string name = "") 
    { 
     var changed = PropertyChanged; 
     if (changed == null) 
      return; 
     changed(this, new PropertyChangedEventArgs(name)); 
    } 

    #endregion 


} 

Обратите внимание на мою ссылку на Settings.Current, нам нужно будет реализовать это сейчас как одноэлементное, но мы будем использовать наш BaseViewModel, поэтому нам не нужно повторно использовать mplement INotifyPropertyChanged:

public class Settings : BaseViewModel 
{ 
    static ISettings AppSettings 
    { 
     get 
     { 
      return CrossSettings.Current; 
     } 
    } 

    static Settings settings; 
    public static Settings Current 
    { 
     get { return settings ?? (settings = new Settings()); } 
    } 

    #region Setting Constants 

    const string HOT_TIME_COUNT_KEY = "hotTimeCount"; 
    static readonly int HOT_TIME_COUNT_DEFAULT = 0; 

    #endregion 

    public int HotTimeCount 
    { 
     get 
     { 
      return AppSettings.GetValueOrDefault<int>(HOT_TIME_COUNT_KEY, HOT_TIME_COUNT_DEFAULT); 
     } 
     set 
     { 
      if (AppSettings.AddOrUpdateValue<int>(HOT_TIME_COUNT_KEY, value)) 
       OnPropertyChanged(); 

     } 
    } 
} 

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

public class MyViewModel : BaseViewModel 
{ 
    private Command increase; 
    public Command IncreaseCommand 
    { 
     get 
     { 
      return increase ?? (increase = new Command(() =>Settings.HotTimeCount++)); 
     } 
    } 
} 

Обратите внимание, что теперь мы наследуемых от BaseViewModel, что означает нашу команду может фактически просто увеличить Settings.HotTimeCount! Но теперь мы должны скорректировать Xaml только немного относительно того, что мы на самом деле привязка данных к нашей метке:

<StackLayout Padding="25"> 

<Button Text="Increase" Command="{Binding IncreaseCommand}"/> 
<Label BindingContext="{Binding Settings}" Text="{Binding HotTimeCount, StringFormat='The time is {0:F0}'}"/> 

</StackLayout> 
</ContentPage.Content> 

Обратите внимание, я устанавливаю BindingContext наших настроек, которая находится в нашем BaseViewModel для Label, это должно быть сделано, потому что именно там он находится. И вот он у вас есть.

Я обновлю свое письмо с этой информацией.

+0

А я вижу, спасибо за это! Я надеялся, что может быть очень короткий способ сделать это? Кажется, что много кода в поцелуй каждый раз, когда я добавляю новое свойство, которое требует привязки. Есть ли другие варианты для этого? –

+0

См. Мой обновленный ответ, это на самом деле очень маленький код, но я переписал его для вас, чтобы он был еще более оптимизирован. – JamesMontemagno

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