2015-10-06 98 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