C#中将WPF属性绑定到ApplicationSettings的最佳方式是什么?

51

如何在C#中将WPF属性绑定到ApplicationSettings中?是否有自动方式类似于Windows Forms应用程序?与此问题类似,如何(是否有可能)在WPF中实现相同的绑定方式?

7个回答

108
您可以直接绑定到Visual Studio创建的静态对象。 在您的Windows声明中添加:
xmlns:p="clr-namespace:UserSettings.Properties"

其中 UserSettings 是应用程序命名空间。

然后,您可以将绑定添加到正确的设置:

<TextBlock Height="{Binding Source={x:Static p:Settings.Default}, 
           Path=Height, Mode=TwoWay}" ....... />

现在,您可以保存设置,例如当您关闭应用程序时:

protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
    Properties.Settings.Default.Save();
    base.OnClosing(e); 
}

2
我很惊讶TwoWay绑定实际上是双向工作的。很好。+1 - Adam Badura
10
搜索者注意,必须选择“双向”选项才能保存设置。试图弄清楚这一点可能会很烦人。 - user1228
4
若想查看略有不同的语法(以及良好的介绍),请阅读http://blogs.msdn.com/b/patrickdanino/archive/2008/07/23/user-settings-in-wpf.aspx。 - Pat
4
虽然这是一个很好的回答问提的方法,但我发现对于工具/选项对话框样式的编辑设置,绑定并不是真正的正确答案;你不想在用户单击“确定”按钮之前将小部件值复制到属性中。在OK点击处理程序中使用显式代码来完成这个操作意味着取消按钮根本不需要处理程序,只要IsCancel == true。 - Peter Wone
@GeorgeBirbilis - Reload会重新加载所有值。这几乎肯定会对那些无处不用绑定的软件产生副作用。 - Peter Wone
显示剩余2条评论

9
如果您是一名尝试使用VB.Net的开发人员,请注意答案会略有不同。
xmlns:p="clr-namespace:ThisApplication"

注意,这里没有.Properties。


在你的绑定中,应该使用MySettings.Default而不是Settings.Default——因为app.config中存储方式不同。

<TextBlock Height={Binding Source={x:Static p:MySettings.Default}, Path=Height, ...

在我抓耳挠腮一阵之后,我发现了这个。希望它可以帮到你。


7
我喜欢被接受的答案,但我遇到了一个特殊情况。 我将文本框设置为“只读”,以便只能在代码中更改其值。 尽管我将模式设置为“TwoWay”,但我无法理解为什么该值未传播回设置。
然后,我发现了这个:http://msdn.microsoft.com/en-us/library/system.windows.data.binding.updatesourcetrigger.aspx 引用如下: 默认情况下是Default,它返回目标依赖属性的默认UpdateSourceTrigger值。 但是,大多数依赖属性的默认值为PropertyChanged,而Text属性的默认值为LostFocus。
因此,如果您的文本框具有IsReadOnly =“True”属性,则必须向Binding语句添加UpdateSourceTrigger = PropertyChanged值:
<TextBox Text={Binding Source={x:Static p:Settings.Default}, Path=myTextSetting, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged} ... />

最佳实践是这样做,仅供参考。 - user1228

5
最简单的方式是绑定到一个公开应用程序设置属性的对象,或将该对象作为StaticResource包含并绑定到该对象。另一种方法是创建自己的Markup Extension,这样您就可以简单地使用PropertyName =“{ApplicationSetting SomeSettingName}”。要创建自定义标记扩展,您需要继承MarkupExtension并使用MarkupExtensionReturnType属性装饰类。John Bowenpost on creating a custom MarkupExtension中介绍了创建自定义MarkupExtension的过程。

3

我喜欢通过ViewModel来实现,然后在XAML中像正常绑定一样进行绑定。

    public Boolean Value
    {
        get
        {
            return Settings.Default.Value;

        }
        set
        {
            Settings.Default.SomeValue= value;
            Settings.Default.Save();
            Notify("SomeValue");
        }
    }

我认为这是大多数情况下最好的解决方案,因为它强制保持一致性。对于用户界面来说,无论值来自设置还是其他任何地方,都没有区别。 - Florian

3

Kris,我不确定这是绑定ApplicationSettings的最佳方法,但这就是我在Witty中所做的。

1)为您想要在窗口/页面/用户控件/容器中绑定的设置创建一个依赖属性。在这种情况下,我有一个用户设置来播放声音。

    public bool PlaySounds
    {
        get { return (bool)GetValue(PlaySoundsProperty); }
        set { SetValue(PlaySoundsProperty, value); }
    }

    public static readonly DependencyProperty PlaySoundsProperty =
        DependencyProperty.Register("PlaySounds", typeof(bool), typeof(Options),
        new FrameworkPropertyMetadata(false, new PropertyChangedCallback(OnPlaySoundsChanged)));

    private static void OnPlaySoundsChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
    {
        Properties.Settings.Default.PlaySounds = (bool)args.NewValue;
        Properties.Settings.Default.Save();
    }

2) 在构造函数中,将属性值初始化为与应用程序设置相匹配的值

      PlaySounds = Properties.Settings.Default.PlaySounds;

3) 在XAML中绑定属性

      <CheckBox Content="Play Sounds on new Tweets" x:Name="PlaySoundsCheckBox" IsChecked="{Binding Path=PlaySounds, ElementName=Window, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

你可以下载完整的 Witty源代码以查看其运行情况,或仅浏览选项窗口的代码

Sasha提供的方法更为简短。 - decasteljau
当你有100多个设置时会发生什么?:O - user1618054

0

同时阅读this文章,了解在BabySmash中如何实现

只有在需要更改通知时,才需要使用DO来支持设置(就像Alan的示例一样)!将绑定到POCO设置类也可以工作!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接