2015-10-06 100 views
0

我已經真正偉大的Xamarin跨平臺設置插件https://components.xamarin.com/view/SettingsPlugin(這樣做的的NuGet版本的PCL是精確的)Xamarin形式設置插件可綁定

它運作良好,但現在用Xamarin形式我真的很想能夠綁定到設置值。 I.e Id喜歡在內容頁面上有一個標籤,上面寫着:「設置值爲:[value]」,並在設置更改時更新。

設置類看起來是這樣的:

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保持不變,但你需要創建視圖模型,如:

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(); 
    } 
} 

這實際上是沒有太多的代碼實際執行爲您的視圖模型將有一個實現INotifyProprety改變BaseViewModel,S Ø真的是你在

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

      Settings.HotTimeCount = value; 
      OnPropertyChanged(); 
     } 

    } 

更神奇的方式只是增加

然而,使用C#的權力和了解數據綁定是如何工作的,你可以先創建一個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的引用,我們需要將它作爲一個singleton實現,但我們將使用我們的BaseViewModel,因此我們不必重新設置i 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(); 

     } 
    } 
} 

現在當然我們還是希望創建,我們的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的標籤,這必須完成,因爲這是它現在所在的位置。在那裏你有它。

我將使用此信息更新自述文件。

+0

啊我明白了,謝謝!我希望可能有一個非常簡短的方法來做到這一點?看起來像很多代碼屁股每次我添加一個新的屬性,需要綁定。還有其他的選擇嗎? –

+0

看到我更新的答案,它實際上是非常少的代碼,但我重寫了它,所以它更加簡化。 – JamesMontemagno