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 に設定します。その後、プロパティを読んだところ、false と表示されましたか? どうしたの?同じオブジェクト (ハッシュコード) と同じスレッドです...わかりません...そして、次の 2 回の読み取りでは、更新すると思いますが、これもまた真実です。最良の部分は、ボックスのチェックを外すとtrueが返されることです。

プロパティ内のコードは hereプロパティ通知からです

出力

setTrue53182860thread1

getFalse53182860thread1

getTrue53182860thread1

getTrue53182860thread1

4

2 に答える 2

2

set メソッドは、新しい値が適用される前に、実際に「get」の呼び出しをトリガーします。これは、関数パラメーターとして ChangeAndNotify への呼び出しに渡す前に、IsSelected プロパティを読み取る必要があるためです。

私はそれを次のように変更します:

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

(関数パラメーターとして渡すときに Get プロパティを呼び出さなくなったことに注意してください。)

于 2012-09-05T04:41:43.847 に答える
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 に答える