为什么我的属性不返回我设置的值?

时间:2012-09-05 04:29:55

标签: c# wpf properties

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

2 个答案:

答案 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属性。)