2013-02-08 21 views
10

私はWPFアプリケーションでMVVMパターンを使用しており、包括的なユニットテストが可能です。 MVVMパターン自体はうまくいっていますが、私はWPFのデザイン時データサポートを使用できるという意味でパターンを適用するのに苦労しています。MVVMパターンでのWPFデザインデータの使用

Iは、ビューモデルのためにそう

public MyView(MyViewModel viewModel) 
{ 
    DataContext = viewModel; 
} 

依存性がそのように

public class MyViewModel 
{ 
    public MyViewModel(IFoo foo, IBar bar) 
    { 
     // ... 
    } 

    // Gets and sets the model represented in the view 
    public MyModel { get; set; } 

    // Read-only properties that the view data binds to 
    public ICollectionView Rows { get; } 
    public string Title { get; } 

    // Read-write properties are databound to the UI and are used to control logic 
    public string Filter { get; set; } 
} 
ように、コンストラクタに注入されるようにビューモデルのインスタンスは、一般に、ビューのコンストラクタに注入されるプリズムを使用しているよう

デザインデータを除いて、これは一般的には本当にうまくいきます。デザインデータ固有のクラスをリリースされたアセンブリにコンパイルすることを避けたいので、の代わりに{d:DesignData}のアプローチを使用することにしましたアプローチですが、これを正しく機能させるには、ViewModelにパラメータのないコンストラクタが必要です。また、XAMLでこれらのプロパティを設定できるようにするために、セッターを持つか、変更可能なコレクションにするために、追加のプロパティを変更する必要があることがよくあります。

public class MyViewModel 
{ 
    public MyViewModel() 
    { 
    } 

    public MyViewModel(IFoo foo, IBar bar) 
    { 
     // ... 
    } 

    // Gets and sets the model represented in the view 
    public MyModel { get; set; } 

    // My read-only properties are no longer read-only 
    public ObservableCollection<Something> Rows { get; } 
    public string Title { get; set; } 

    public string Filter { get; set; } 
} 

これは私を心配されています

  • 私が呼ばれることを意図されることはありませんパラメータなしのコンストラクタを持っており、ユニットではありませんが、その唯一のViewModel自体がすべきプロパティのセッターがあり
  • をテスト呼び出す予定
  • 私のViewModelは、ビューによって修正されるべきプロパティと、そうであってはならない混乱した混合物になっています。これにより、特定のプロパティを維持する責任を負うコードを一目で分かりやすくします。
  • デザイン時に特定のプロパティを設定する(例: Filterテキストのスタイリングを見るために)実際にViewModelロジックを呼び出すことができます!妥協しない方法で、WPF MVVMアプリケーションでのデザイン時データを取得するためのより良い方法はあり

(ので、私のViewModelも設計時に不足しているそれ以外の場合は必須依存関係のtollerantする必要があります)私のこのようにViewModel?

また、ViewModelを別の方法で構築して、ロジックが別の場所に分かれたよりシンプルなプロパティを持つようにする必要があります。

答えて

-1

私もWPFとMVVMの実装でNUnitテストを行っています。しかし、私のバージョンはあなたのものとは逆です。最初にビューを作成してから、それを制御するモデルを作成しています。

私のバージョンでは、MVVMモデルFIRSTを作成して、牛が家に帰るまでユニットテストをして、ビジュアルデザインを心配する必要はありません。モデルが壊れている場合は、視覚的な実装も同様です。

私のMVVMモデルでは、 "GetTheViewWindow"メソッドがあります。 MVVMのベースラインから派生すると、それぞれのビューモデルには独自のビューがあります。したがって、仮想メソッドを使用すると、各インスタンスはプロダクションに適用されるときに独自の新しいビューウィンドウを実行します。

public class MyMVVMBase 
{ 
    private MyViewBaseline currentView; 

    public MyMVVMBase() 
    { // no parameters required } 

    public virtual void GetTheViewWindow() 
    { throw new exception("You need to define the window to get";) } 
} 

public class MyXYZInstanceModel : MyMVVMBase 
{ 
    public override void GetTheViewWindow() 
    { 
     currentView = new YourActualViewWindow(); 
    } 
} 

これは、実行しているものの代替として役立ちます。

+2

あなたのVMがあなたの意見に依存していることは私にはちょっと変です。 –

+0

@GregD、私にではありません。私はこのモデルを使ってデータを照会でき、ゲッター/セッターを公開して外部の "ビュー"に表示されるフラグを設定することができます。私は、この例ではビューを要求していないと言っていますが、起動する場合、各ビューモデルには保守画面、トランザクションヘッダー/ディテール処理などの目的があります。対応するビューがある場合は、このmvvmハンドラに関連付けられたビューを呼び出すようにしてください。 – DRapp

+0

デザインタイムデータはこのアプローチでどのように機能しますか? – Justin

1

まず、this videoを参照することをお勧めします。ここで、Brian LagunasはMVVMに関するいくつかのベストプラクティスを提供しています。ブライアンは少なくともプリズムの開発に携わっています。彼の名前はナゲットのパッケージ情報に現れます。さらにチェックしなかった。私の側に

私はプリズムのビットを使用し、そして(ブライアンは示してどのように)、データコンテキストは、ビューのXAMLに割り当てられ、私のモデルとのViewModelは常に空白のコンストラクタを提供し、私は次のようにプロパティ値を設定します。

<MyView.DataContext> 
    <MyViewModel /> 
</MyView.DataContext> 

public void BringSomethingNew() 
{  
    var myView = new View(); 
    (myView.DataContext as ViewModel).Model = myModel; 

    UseMyView(); 
} 

このアプローチのもう一つの利点は、ViewModelには、設計時に同じパスで、一度作成し、以下のオブジェクトを作成し、GCの努力を保存するので、時間を実行していることです。私はこれがエレガントだと分かりますセッターに関して

あなたがそれらをプライベートにする場合は、設計データはまだのように、動作します:

public string MyProp { get; private set; } 

[OK]を、あなたの都合の良い時NotifyPropertyChangeを管理するためにそれをカスタマイズし、あなたのアイデアを持っています。

今、私はまだObesrvableCollectionを管理する解決策はありません(同じ問題に直面しますが、XAMLに複数の値を設定することは時々... ???)、はい、私はあなたがコンストラクタでデフォルト値を設定するなど、プロパティが設定されていない場合は管理します。

こちらがお役に立てば幸いです。

関連する問題