我有一个简单的wpf复选框
<CheckBox Name="layerCheckBox" IsChecked="{Binding Path=IsSelected, Mode=TwoWay}" Grid.Column="0" />
我绑定到我的自定义Layer类的BindingList。
public BindingList<Layer> Layer
{
get { return _layer; }
set { _layer = value; }
}
Layer类具有IsSelected属性。这就是我在复选框中使用的内容。如您所见,我添加了一些输出来读取和写入属性
public bool IsSelected
{
get
{
System.Diagnostics.Debug.WriteLine("get"+_isSelected+this.GetHashCode()+
"thread"+Thread.CurrentThread.ManagedThreadId);
return _isSelected;
}
set
{
System.Diagnostics.Debug.WriteLine("set" + value + this.GetHashCode()
+ "thread" + Thread.CurrentThread.ManagedThreadId);
PropertyChanged.ChangeAndNotify(ref _isSelected, value, () => IsSelected);
}
}
奇怪的是输出。首先,我选中复选框,并将属性设置为true。后来我读了财产,它说错了吗?这是怎么回事?它是相同的对象(哈希码)和相同的线程...我不明白...而对于接下来的2次读取,我猜是刷新,它再次成真。最好的部分是 - 如果我取消选中该框,则返回true。
该属性中的代码来自此处property notify
输出
setTrue53182860thread1
getFalse53182860thread1
getTrue53182860thread1
getTrue53182860thread1
答案 0 :(得分:2)
问题可能是ChangeAndNotify
扩展方法。它在提升属性更改事件后设置字段的值。
当您举起活动时,所有订阅者都将尝试从该属性中读取。由于尚未设置支持字段,因此它将返回原始值。
修复ChangeAndNotify
扩展方法中的代码,以便在引发Property Change事件之前设置字段的值。
field = value; //<-- move to here
if (vmExpression != null)
{
LambdaExpression lambda = Expression.Lambda(vmExpression);
Delegate vmFunc = lambda.Compile();
object sender = vmFunc.DynamicInvoke();
if( handler != null)
{
handler(sender, new PropertyChangedEventArgs(body.Member.Name));
}
}
return true;
答案 1 :(得分:2)
在应用新值之前,您的set方法实际上会触发对'get'的调用。这样做是因为它需要在将IsSelected属性作为函数参数传递给您调用ChangeAndNotify之前读取它。
我会将其更改为:
set { PropertyChanged.ChangeAndNotify(ref _isSelected, value, () => _isSelected); }
(请注意,作为函数参数传递时,不再调用Get属性。)