1

WPF に少し問題があることに気付きました。chain でプロパティを双方向にバインドする場合は、(A <-> B, B <-> C, C <-> D ...)2 つ以上のコンバーターを導入するまでは問題ありません。

現在、1 つのコンバーターでも機能しますが、チェーンに 2 つのコンバーターを追加すると(A <x> B, B <-> C, C <x> D ...)、プロパティが十分に速く変化すると、無限ループに陥る可能性があります。

WPF は無限の再帰を回避することについて非常に賢明であるように見えますが、変更が速すぎると、ブロックしているものをハードルし、無限に進みます。

これに気付いたのは、自分でカラー エディターを試作していたときです。色の選択は、色相と明度を交差させたビットマップと、別のスライダーの彩度で実現したかったのです。スライダーが同期していることを確認するために、コンバーターとバインドする必要がありました (色との間)。ここで、計算の問題に遭遇したので、変換を管理するクラスを作成しましたが、必要な場合にのみ実行し、すべてをそれにバインドしました。問題は、ユーザーがカラー パレットを非常に速く移動した場合に、自分の制御範囲外にバインドしたときに無限再帰に遭遇することです。

興味深い効果までたどり着きました。コンバーター (双方向としてセットアップされている場合) は、前方にトリガーされ、変換損失を反映するためにすぐに戻ります。しかし、同じことを行う別のコンバーターとチェーンすると、ピンポンのように無限に前後に跳ね返ります.

これは、コンバーターが十分に速くトリガーされた場合にのみ発生しました。したがって、再帰スタックをカウントする値をオーバーフローさせたと推測しています。

あなたのコントロールの「結果値プロパティ」に対してバインディングを使用するときに、このような問題をどのように回避できますか?

4

1 に答える 1

1

コンバーターが正確でない場合 (数値計算がある場合など)、これと同様の方法でチェーンを切断する必要があります...

プロパティ通知用

それ以外の:

public double MyProperty
{
    get
    {
        return _myProperty;
    }
    set
    {
        if (value != _myProperty)
        {
            _myProperty = value;
            NotifyPropertyChanged("MyProperty");
        }
    }
}

使用する:

public double MyProperty
{
    get
    {
        return _myProperty;
    }
    set
    {
        if (Abs(value - _myProperty) / (Max(Abs(value), Abs(_myProperty)) + double.Epsilon) > MyEpsilon)
        {
            _myProperty = value;
            NotifyPropertyChanged("MyProperty");
        }
    }
}

または、同様の不正確な比較で、不正確さが無限ループを作成しないようにします。

依存関係プロパティの場合

Register(String, Type, Type, PropertyMetadata, ValidateValueCallback)とを使用PropertyMetadata(Object, PropertyChangedCallback, CoerceValueCallback)して CoerceValueCallback を定義し、小さな変更を防ぎます (上記と同じアルゴリズムを使用)。

于 2012-06-08T20:06:38.277 に答える