0

我有一个简单的 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 的框。

属性内的代码来自here property notify

输出

setTrue53182860thread1

getFalse53182860thread1

getTrue53182860thread1

getTrue53182860thread1

4

2 回答 2

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;
于 2012-09-05T04:34:24.040 回答
2

在应用新值之前,您的 set 方法实际上会触发对“get”的调用。这样做是因为它需要先读取 IsSelected 属性,然后再将其作为函数参数传递给您对 ChangeAndNotify 的调用。

我会将其更改为:

set { PropertyChanged.ChangeAndNotify(ref _isSelected, value, () => _isSelected); }

(请注意,当作为函数参数传递时,您不再调用 Get 属性。)

于 2012-09-05T04:41:43.847 回答