WPF 绑定因 INotifyPropertyChanged.PropertyChanged 的自定义添加和删除访问器而失败
我有一个场景导致 WPF 数据绑定和 INotifyPropertyChanged 出现奇怪的行为。我想要数据绑定源的私有成员来处理 INotifyPropertyChanged.PropertyChanged 事件。
这是源代码:
XAML
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="TestApplication.MainWindow"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Height="100" Width="100">
<StackPanel>
<CheckBox IsChecked="{Binding Path=CheckboxIsChecked}" Content="A" />
<CheckBox IsChecked="{Binding Path=CheckboxIsChecked}" Content="B" />
</StackPanel>
</Window>
正常实现有效
public partial class MainWindow : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public bool CheckboxIsChecked
{
get { return this.mCheckboxIsChecked; }
set
{
this.mCheckboxIsChecked = value;
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs("CheckboxIsChecked"));
}
}
private bool mCheckboxIsChecked = false;
public MainWindow() { InitializeComponent(); }
}
所需的实现不起作用
public partial class MainWindow : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged
{
add { lock (this.mHandler) { this.mHandler.PropertyChanged += value; } }
remove { lock (this.mHandler) { this.mHandler.PropertyChanged -= value; } }
}
public bool CheckboxIsChecked
{
get { return this.mHandler.CheckboxIsChecked; }
set { this.mHandler.CheckboxIsChecked = value; }
}
private HandlesPropertyChangeEvents mHandler = new HandlesPropertyChangeEvents();
public MainWindow() { InitializeComponent(); }
public class HandlesPropertyChangeEvents : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public bool CheckboxIsChecked
{
get { return this.mCheckboxIsChecked; }
set
{
this.mCheckboxIsChecked = value;
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs("CheckboxIsChecked"));
}
}
private bool mCheckboxIsChecked = false;
}
}
I have a scenario which is causing strange behavior with WPF data binding and INotifyPropertyChanged
. I want a private member of the data binding source to handle the INotifyPropertyChanged.PropertyChanged
event.
Here's the source code:
XAML
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="TestApplication.MainWindow"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Height="100" Width="100">
<StackPanel>
<CheckBox IsChecked="{Binding Path=CheckboxIsChecked}" Content="A" />
<CheckBox IsChecked="{Binding Path=CheckboxIsChecked}" Content="B" />
</StackPanel>
</Window>
Normal implementation works
public partial class MainWindow : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public bool CheckboxIsChecked
{
get { return this.mCheckboxIsChecked; }
set
{
this.mCheckboxIsChecked = value;
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs("CheckboxIsChecked"));
}
}
private bool mCheckboxIsChecked = false;
public MainWindow() { InitializeComponent(); }
}
Desired implementation doesn't work
public partial class MainWindow : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged
{
add { lock (this.mHandler) { this.mHandler.PropertyChanged += value; } }
remove { lock (this.mHandler) { this.mHandler.PropertyChanged -= value; } }
}
public bool CheckboxIsChecked
{
get { return this.mHandler.CheckboxIsChecked; }
set { this.mHandler.CheckboxIsChecked = value; }
}
private HandlesPropertyChangeEvents mHandler = new HandlesPropertyChangeEvents();
public MainWindow() { InitializeComponent(); }
public class HandlesPropertyChangeEvents : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public bool CheckboxIsChecked
{
get { return this.mCheckboxIsChecked; }
set
{
this.mCheckboxIsChecked = value;
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs("CheckboxIsChecked"));
}
}
private bool mCheckboxIsChecked = false;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我的工作解决方案几乎与我的问题中的“所需实现”完全相同,只是添加了 Sender 属性。
这个示例有点人为,但在我的应用程序中,将事件处理代码移到绑定类之外是有意义的。
My working solution is almost exactly the same as the "desired implementation" in my question, with the addition of the Sender property.
This example is a bit artificial, but in my application moving the event handling code outside of the bound class makes sense.
这只是一个猜测,但我认为这可能是因为传递给事件处理程序的
sender
参数是HandlesPropertyChangeEvents
的实例,而绑定需要的实例主窗口
。尝试更改您的代码,以便发送者是
MainWindow
实例:That's just a guess, but I think it might be because the
sender
parameter passed to the event handler is an instance ofHandlesPropertyChangeEvents
, when the binding expects an instance ofMainWindow
.Try to change your code so that the sender is the
MainWindow
instance :