3

次のように、値が互いに依存する変数がいくつかある状況があります。

A は B と C の関数 B は A と C の関数 C は A と B の関数

どちらの値も UI で変更できます。私は次のように計算と変更通知を行っています:

private string _valA;
private string _valB;
private string _valC;

public string ValA
{
    get { return _valA; }
    set
    {
        if (_valA != value)
        {
            _valA = value;
            RecalculateValues("ValA");       //Here ValB and ValC are calculated
            OnPropertyChanged("ValA");
        }
    }
}

public string ValB
{
    get { return _valB; }
    set
    {
        if (_valB != value)
        {
            _valB = value;
            RecalculateValues("ValB");       //Here ValA and ValC are calculated
            OnPropertyChanged("ValB");
        }
    }
}

(...)

private void RecalculateValues(string PropName)
{
    if (PropName == "ValA")
    {
       _valB = TotalValue * _valA;
       OnPropertyChanged("ValB");

       _valC = something * _valA
       OnPropertyChanged("ValC");
    }
    else
    (...)

}

変更された変数のセッターで計算メソッドを呼び出し、_valB、_valC (たとえば) の値を計算してから、これらの値に対して PropertyChanged を呼び出しています。変数間の依存関係のために、私はこのようにしています。このように、どの変数が正しい値で計算されるかを制御できます。また、他の変数の PropertyChanged をトリガーし、変数のゲッターで計算を実行することも考えましたが、以前にどのプロパティが変更されたかを知り、その値を使用する必要があります...それが最善/最も簡単な解決策かどうかはわかりません。

これはこれを行う良い方法ですか?セッターブロックでこれを実行するという考えは好きではありませんが、現時点ではそれを行うためのより良い方法がわかりません。

もう 1 つの問題は、IdataErrorInfo を使用して検証/エラー情報を UI に表示することです。問題は、this[columnName] インデクサーがセッターの最後に呼び出され、計算の前に値を検証する必要があったため、値が入力は有効ではありません計算は行われません.IDataErrorInfoを放棄し、計算が行われる前に検証メソッドを呼び出すことを真剣に検討しています. それを明示的に呼び出す方法、または値の属性の直後に呼び出す方法はありますか?

注: ViewModel から別のオブジェクトで検証ロジックを呼び出す必要があるため、ValidationRules はオプションではありません。

4

2 に答える 2

2

スレッドをブロックせず、CPU を集中的に使用する重い計算に入らない限り、Setter で Validation と Calculation を呼び出しても問題ありません。複雑なループを含まない単純な 5 ~ 10 個の数学ベースのステートメントがある場合は、問題ありません。

データバインディングと WPF の場合、これが唯一の方法ですが、BeginEdit、CancelEdit、および EndEdit を持つ IEditableObject という実装がもう 1 つあります。ここでは、「EndEdit」関数で計算と検証を行うことができます。

BeginEdit では、すべての値を一時ストレージに保存できます。CancelEdit では、temp からすべての値を戻し、変更されたすべての値に対して PropertyChaged イベントを発生させることができます。EndEdit では、最終的にすべての変数を更新し、それらすべてに対して PropertyChanged を発生させることができます。更新しました。

IEditableObject はパフォーマンスの点で最適ですが、キャンセルまたは終了するまで新しい値を表示しない場合がありますが、すぐに表示する唯一の方法は、あなたが行っている方法です。

CPUの使用率が高い場合は、別のスレッドを呼び出して計算を行い、変数を設定し、最後にPropertyChangedを起動できますが、技術的には、セッターで値を設定しながら非同期で同じことを行っています.

于 2009-12-28T07:51:36.427 に答える
1

クラス内のどこからでもNotifyPropertyChangedを呼び出すことができるため、これを単純化する1つの方法は、Calculateメソッドで3つの変数すべてに対してNotifyPropertyChangedを起動することです。複数の依存関係を持つ複雑な計算がある場合は、このトリックを使用します。セッターでイベントを発生させたい場合もあります。その場合、イベントが2回発生しないように、計算内からプロパティを更新するときにフラグフィールドを使用してイベントを無効にします。

于 2009-12-28T22:01:58.507 に答える