我遇到绑定到WPF表单的问题。我有自己的静态“设置”类(单例),它实现了PropertyChangedEventHandler,并在更新属性时引发事件。
单例对象被添加到表单构造函数中的资源中,并且在表单初始化时正确读取属性,从而表明绑定是正确的。
但是,WPF不会为PropertyChangedEventHandler注册任何事件处理程序,并且PropertyChanged始终为null。因此,事件永远不会被提出,我的表单永远不会更新(它意味着在点击按钮时更新)。
我做错了什么?
我怀疑由于某种原因调用Resources.Add会阻止WPF注册自己的事件处理程序,但我不确定。
我已经阅读了关于类似主题的多个SO问题,但是最常见的两个问题是没有创建一个合适的单例(因此将另一个实例传递给xaml然后打算)或者没有实现INotifyPropertyChanged。我正确地做了这两件事。
预期行为:
Settings.TextValue是我感兴趣的属性。在其setter中,NotifyPropertyChanged被调用,遗憾的是它无法引发this.PropertyChanged事件,因为WPF没有注册处理程序。
单击MainWindow.Button1时,textBox的值应从Settings.TextBox(“testOK”)的初始值更改为“ButtonA OK”。
以下是代码:
Settings.cs:
namespace bindings
{
public sealed class Settings : INotifyPropertyChanged
{
private static readonly Settings instance = new Settings();
private Settings()
{
}
public static Settings Instance { get { return instance; } }
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName = null)
{
// passing propertyName=null raises the event for all properties
if (PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
private string textValue = "testOK";
public static string TextValue
{
get { return Instance.textValue; }
set { Instance.textValue = value; Instance.NotifyPropertyChanged(); }
}
}
MainWindow.xaml.cs
namespace bindings
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
Resources.Add("foobar", Settings.Instance);
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
}
private void button1_Click(object sender, RoutedEventArgs e)
{
int hash = Settings.Instance.GetHashCode();
Settings.TextValue = "ButtonA OK";
}
}
}
MainWindow.xaml
<Window x:Class="bindings.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded" WindowStyle="ToolWindow">
<Grid PresentationTraceSources.TraceLevel="High" DataContext="{StaticResource foobar}">
<Button Content="ButtonA" Height="33" HorizontalAlignment="Left" Margin="76,243,0,0" Name="button1" VerticalAlignment="Top" Width="101" Click="button1_Click" />
<TextBox Height="28" HorizontalAlignment="Left" Margin="182,180,0,0" Name="textBox1" VerticalAlignment="Top" Width="93"
Text="{Binding Path=TextValue, Mode=OneWay}" DataContext="{Binding}" PresentationTraceSources.TraceLevel="High"/>
</Grid>
</Window>
感谢您的帮助!