在我的WPF应用程序中,我有一个CheckBox
,其IsChecked
值绑定到我的viewmodel中的属性。请注意,我已经注释掉了在viewmodel中设置值的实际行。这是标准模式:
<CheckBox IsChecked="{Binding Path=SomeProperty}" />
public bool SomeProperty
{
get { return this.mSomeProperty; }
set
{
if (value != this.mSomeProperty)
{
//this.mSomeProperty = value;
NotifyPropertyChanged(new PropertyChangedEventArgs("SomeProperty"));
}
}
}
当我点击CheckBox
时,我预计不会发生任何事情,因为this.mSomeProperty
的值未设置。但是,观察到的行为是CheckBox
正在被检查和取消选中,无论this.mSomeProperty
的值如何。
发生了什么事?为什么我的绑定不会强制CheckBox
显示底层数据模型的设置?
答案 0 :(得分:3)
因为更新源后WPF不会自动从绑定源重新加载。这可能部分是出于性能原因,但主要是为了处理绑定失败。例如,考虑绑定到整数属性的TextBox。假设用户键入123A。 WPF希望继续显示用户输入的内容,以便他们可以更正它,而不是突然将TextBox内容重置为属性的旧值。
因此,当您单击CheckBox时,WPF会假定它应该继续显示 control 状态,而不是重新检查绑定属性。
我发现这个不太优雅的唯一方法是在 WPF从调用属性设置器返回后引发PropertyChanged 。这可以使用Dispatcher.BeginInvoke:
完成set
{
// ...actual real setter logic...
Action notify = () => NotifyPropertyChanged(...);
Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, notify);
}
通过将其合并到NotifyPropertyChanged实现中可以使这一点变得不那么可怕,这样您就不必使用此实现问题来污染单个属性。您也可以使用NotifyOnSourceUpdated和SourceUpdated附加事件,但我没有探究过这种可能性。