在 C# 中将 WPF 属性绑定到 ApplicationSettings 的最佳方法?
Posted
技术标签:
【中文标题】在 C# 中将 WPF 属性绑定到 ApplicationSettings 的最佳方法?【英文标题】:Best way to bind WPF properties to ApplicationSettings in C#? 【发布时间】:2010-09-14 08:22:06 【问题描述】:在 C# 中将 WPF 属性绑定到 ApplicationSettings 的最佳方法是什么?有没有像 Windows 窗体应用程序那样的自动方式?类似于this question,您如何(并且有可能)在 WPF 中做同样的事情?
【问题讨论】:
【参考方案1】:您可以直接绑定到 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);
【讨论】:
我很惊讶TwoWay
绑定实际上以两种方式工作。好的。 +1
注意搜索者,TwoWay 是必需的,否则设置将不会被保存。很烦人试图弄清楚那个。
对于稍微不同的语法(和好的介绍),阅读blogs.msdn.com/b/patrickdanino/archive/2008/07/23/…
虽然这是对所提问题的一个很好的回答,但我发现绑定并不是编辑设置的工具/选项对话框样式的真正正确答案;在用户单击“确定”按钮之前,您不想将小部件值复制到属性中。在 OK 点击处理程序中使用显式代码来执行此操作意味着取消按钮根本不需要处理程序提供 IsCancel == true
@PeterWone 从我读过的内容中保留使用 Properties.Settings.Default.Save() 所需的设置,因此在属性编辑对话框上的取消操作的场景中,您将使用Properties.Settings.Default.Reload() [然后在确定时调用 Save]【参考方案2】:
如果您是尝试此操作的 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, ...
在拉了一点头发之后,我发现了这一点。希望对你有帮助
【讨论】:
【参考方案3】:我喜欢接受的答案,但我遇到了一个特殊情况。我将文本框设置为“只读”,这样我只能在代码中更改它的值。我不明白为什么该值没有传播回设置,尽管我将模式设置为“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 ... />
【讨论】:
最佳做法是这样做,恕我直言。【参考方案4】:最简单的方法是绑定到将您的应用程序设置作为属性公开的对象,或者将该对象包含为 StaticResource 并绑定到该对象。
您可以采取的另一个方向是创建自己的Markup Extension,这样您就可以简单地使用 PropertyName="ApplicationSetting SomeSettingName"。要创建自定义标记扩展,您需要继承 MarkupExtension 并使用 MarkupExtensionReturnType 属性装饰类。 John Bowen 有一个 post on creating a custom MarkupExtension 可能会使流程更清晰。
【讨论】:
【参考方案5】:Kris,我不确定这是绑定 ApplicationSettings 的最佳方式,但我在 Witty 中就是这样做的。
1) 在 window/page/usercontrol/container 中为要绑定的设置创建依赖属性。这是我有一个播放声音的用户设置的情况。
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 source 以查看它的实际效果,或仅浏览code for options window。
【讨论】:
sasha 的方法(见其他答案)更短 呃,当你有 100 多个设置时会发生什么? :O【参考方案6】:我喜欢通过 ViewModel 来做,只是在 XAML 中正常进行绑定
public Boolean Value
get
return Settings.Default.Value;
set
Settings.Default.SomeValue= value;
Settings.Default.Save();
Notify("SomeValue");
【讨论】:
我认为这是大多数情况下的最佳解决方案,因为它强制一致性。对于 UI,如果值来自设置或其他任何地方,则没有区别。【参考方案7】:另请阅读 this 关于如何在 BabySmash 中完成的文章
如果您需要更改通知,您只需使用 DO 支持设置(如 Alan 的示例)!绑定到 POCO 设置类也可以!
【讨论】:
以上是关于在 C# 中将 WPF 属性绑定到 ApplicationSettings 的最佳方法?的主要内容,如果未能解决你的问题,请参考以下文章
在 Blazor 中将 HTML 元素的值绑定到 C# 属性
在 C# 中将 Windows 窗体属性绑定到 ApplicationSettings 的最佳方法?