web-dev-qa-db-ja.com

ビューモデルでモデルを拡張するためのベストプラクティス

GUIを実装したいモデルがあるという問題に直面しています。私はMVVMとWPFを探索しているので、もちろん、ビューとモデルの間でビューモデルを使用します。 GUIでドラッグできるオブジェクトを表すいくつかのモデルクラスに座標を追加する必要もあります。現時点では、これが私が必要とするこれらの特定のモデルクラスへの唯一の追加です。少なくとも現時点では。同時に、すべてではないにしても、ほとんどすべてのモデルオブジェクトに含まれる情報は、ビューにとって重要です。

最も重要なモデルクラスは次のとおりです。

  • テーブル
  • カラム
  • 依存関係

  • テーブルはその列を認識しています。

  • 列は、どのテーブルに属しているかを認識しています。
  • 列は1 .. *の依存関係を知っている
  • 依存関係は、依存関係を表す1 .. *列を知っています。

もちろん、必要に応じて、これらのオブジェクトが互いを認識する方法を変更することもできます。

ただし、ここでの本当の問題は、テーブル、列、依存関係に座標を追加すると同時に、モデルクラスをビューで使用できるようにするにはどうすればよいですか?

1つの方法は、次のようなものを作成することです。

public class TableViewModel
{
    public Model.Table ModelTable { get; private set; }
    public List<ColumnViewModel> Columns { get; set; }
    public float X { get; set; }
    public float Y { get; set; }
}

これは、「拡張された」モデルオブジェクトをビューに転送するための好ましい方法ですか、それともこのタスク用に特別に設計されたパターンがありますか?

モデルとビューモデルのオブジェクト間の通常の継承は機能しますか?私にはわかりませんが、原因となるカップリングが好きです。

または、ビューに合うように調整されたビューモデルクラスを作成し、モデルオブジェクトからビューモデルオブジェクトにプロパティをマップする必要がありますか?これにより、ビューとモデル間の結合が完全に削除されますが、メモリ内に2つのオブジェクトが作成されます。この場合、これらは非常に大きなモデルになる可能性があります。ビューモデルにマップされた後、ガベージコレクターはそれらへの参照がなくなるため、モデルオブジェクトを削除しますか?

2
Anders

ただし、ここでの本当の問題は、テーブル、列、依存関係に座標を追加すると同時に、モデルクラスをビューで使用できるようにするにはどうすればよいですか?

あなたのサンプルViewModelはうまくいくはずです。私がそれを達成したのを見た別の方法は、すべてのViewModelが継承し、モデルのタイプを取得し、それをBaseViewModel<T>として公開するT Model { get; }クラスを使用することです。

これは、「拡張された」モデルオブジェクトをビューに転送するための好ましい方法ですか、それともこのタスク用に特別に設計されたパターンがありますか?

ViewModelは、モデル/データを取得し、ビューが必要とするUI状態を維持および変更する責任があります。あなたのサンプルViewModelはこの責任に適合するようです。ただし、ViewModelと連動する「サブビュー」も表示する場合は、ViewModel内でViewModelクラスのみを使用します。たとえば、List<ColumnViewModel>を使用するのは、それらをループして、ColumnViewModelに関連付けられたコントロールを動的に追加または含める場合のみです。

モデルとビューモデルのオブジェクト間の通常の継承は機能しますか?

うまくいくかもしれませんが、モデルからViewModelを継承すると混乱を招くでしょう。さらに、モデルが実際にモデルオブジェクトのリストである場合はどうなりますか?その場合、基本クラスをList<Model>にする必要があり、不要なメソッドの束をビューに公開するため、継承はその場合よりトリッキーになります。ラッピングの方が良いと思います。

または、ビューに合わせて調整されたビューモデルクラスを作成し、モデルオブジェクトからビューモデルオブジェクトにプロパティをマップする必要がありますか?

ViewModelは通常、ビューの特定のニーズに合わせて調整されます。私はViewModelをビューの分離コードと考える傾向があります。モデルプロパティのマッピングは、通常、WPFビューのバインディングを通じて行われます。

ビューモデルにマップされた後、ガベージコレクターはそれらへの参照がなくなるため、モデルオブジェクトを削除しますか?

これはすべて、コンテキスト、問題のオブジェクトが保持する参照、およびその他のさまざまな要因によって異なります。一般的に、ビューモデルはビューと同じ存続期間を持ち、データを含みます。ただし、特定のパフォーマンスの懸念がある場合は、モデルが読み込まれたら、いつでも手動でモデルをクリアできます。

4
Aaron Hawkins