12

これは、アーキテクチャ/設計の問題です。

私は過去に WPF/Windows フォームなどで書かれたいくつかのプロジェクトに出くわしました.多くのフィールドを持つ複雑な画面があり、これらのフィールドは互いに接続されています(それらの値はいくつかのロジックが関与して互いに依存しています)。

実装後に私が引き受けたこれらのプロジェクトは、多くのイベント/データ バインド地獄を発見しました。つまり、これらのフィールドはすべて他のフィールドに依存しているため、INotifyPropertyChanged を実装し、他のフィールドは変更されているということです。結果。これにより、画面が読み込まれるときに同じフィールドが 5 ~ 6 回更新され、フィールドが入力される順序によって恐ろしいバグが発生します。(たとえば、Dateは Job Typeの後ではなくJob Typeの前に設定されたので、別のJob Feeになります。)

さらに悪いことに、一部のハックは UI イベントに実装されています (たとえば、DropDown がフィールド X を更新するように変更された) 一方で、他のものは UI がバインドするドメイン モデルに実装されています。

基本的に、これは大混乱です。ゼロから始める場合、このようなものを実装する最良の方法は何かを知りたいだけです。それとも、そもそもそのような複雑な画面は避けた方がよいのでしょうか?

4

2 に答える 2

2

ビジネスロジックをプロパティセッターからできるだけ遠ざけるようにします。

まず、1 つの計算に複数のプロパティが必要な場合は、計算を実行するメソッドを 1 つ作成し、必要に応じてそのメソッドを呼び出します。たとえば、プロパティ値のすべての異なる組み合わせが理にかなっている場合、各プロパティのセッターでメソッドを呼び出して、プロパティの 1 つが変更されるたびに同じコードが実行されるようにすることができます。プロパティ値の特別な組み合わせしか評価できない場合は、コマンドを実装して結果の変更をいつ計算するかをユーザーに決定させるか、検証を通じてフィードバックを提供し、組み合わせが有効な場合にのみプロパティの変更を評価することができます。相互に依存するプロパティがいくつかある場合は、「ChangeInitiator」変数を使用してどのプロパティが変更されたかを示すことがよくあります。これにより、どのプロパティが変化の原因であり、結果としてどのプロパティが変化する必要があるかが計算方法で明確になります。基本的に、これは各プロパティ セッターで計算の一部を実行するのと同じですが、関係のさまざまな部分がすべて 1 つのメソッドにまとめられていると、全体像をつかむのに役立つことがわかりました。

私がかつて書いたプログラムでは、バックグラウンド スレッドで定期的にいくつかの計算を実行していたので、新しい計算が必要なデータの一部が変更されるたびにフラグを設定し、タイマーに基づいてすべての更新を約 1 秒ごとに実行していました。 ...これは、ロジックをより明確にするのにも役立ちます。また、関連する変更の 1 つのセットに対して計算を複数回実行する必要がなくなります。

変更通知に関しては、UI データ バインディングにのみ使用したいと思います。

于 2013-05-03T06:38:02.283 に答える
0

かなり複雑な UI (たとえば、DataGrid の行など、さまざまなタイプの関連フィールドをいくつか含む) があり、MVVM パターンは非常にうまく機能しています。モデルから取得され、関連する複雑なロジックを持つビューに公開されるすべてのプロパティは、バッキング フィールドを持たず、モデルを直接指すビューモデルの同等のプロパティによって「ラップ」されます。

public class SomeComplexViewModel
{

    public SomeModel Model {get;set;}

    public string SomeCrazyProperty
    {
       get
       {
          return Model.SomeCrazyProperty;
       }
       {
          Model.SomeCrazyProperty = value;
          //... Some crazy logic here, potentially modifying some other properties as well.
       }
    }
}

<TextBox Text="{Binding SomeCrazyProperty}"/>

これにより、「初期値」の問題が解消されます。バインディングによって読み取られる初期値は、実際にはモデルから取得される実際の値であり、したがって、に配置されたロジックSetterは必要な場合にのみ実行されます。

次に、ダミー プロパティ (背後にロジックがない) については、ビューからモデルに直接バインドします。

<TextBox Text="{Binding Model.SomeRegularProperty}"/>

これにより、ViewModel の肥大化が軽減されます。

コードビハインドのイベントに関しては、私はそれを完全に避けています。私のコード ビハインド ファイルは、ほぼ常に 1 つInitializeComponent()だけです。

XAML で直接実行できない場合、またはコードで実行する方が簡単な場合 (ほとんどの場合はそうではありません)、ビュー固有のロジックのみがコード ビハインド (アニメーションなど) に配置されます。

編集:

winforms のバインド機能は、XAML ベースの機能と比較すると冗談であることに注意してください。それが、これらのプロジェクトで恐ろしい混乱を引き起こしている原因でしょうか?

于 2013-05-03T01:27:48.830 に答える