2009-03-16 7 views
3

MVVMパターンを使ってすべてのものがどのようにフィットするかを頭に浮かべています。実際にはすべてシンプルなようですが、実装しようとすると、私がコーディングしようとする他のさまざまなルールが破られているようです。MVVM - 何を何に含めるべきか...何を作成する必要があります

SilverlightまたはWPFではなく、Flexを使用してパターンを実装しようとしています。誰にもこのような理由がないとわかっている場合は、 。

私にはいくつかの意見があります。時には同時に2つのビューをページに表示する必要があります。時々私は単一のビューに戻る。私の通常のFlexの脳では、他のすべてのビュー(コードビハインドと同じように)を含むコードビハインドのメインビューがあります。そのメインビューは、他の個々のビューの切り替えを行います。

MVVMでこれを実装しようとすると、ViewModelsから私のViewsを切り離すバインディングを使用して、MVVMの原則に固執しようとしています。アプリケーション全体の状態でViewModelを作成し、ApplicationViewがそのデータにバインドし、サブビューのすべての切り替えを実行したとします。

ここで、私のサブビュー用のビューモデルを作成する必要がありますか?私はApplicationViewの中で試しました - それは正しいように見えませんでした。そして、私はアプリケーションビューの外で試して、そのインスタンスをApplicationViewに渡してから、私のサブモデルにバインドしました。何か不足していますか?これらの方法のどれも、これを切り離そうとする全体的なポイントには適していないようです。

この問題を説明している良い本やリンクは、非常に高く評価されます。

乾杯、 ジェームズ

答えて

7

あなたが参照しているアプローチは、ViewModelの構成です。独自のViewModelエンティティにバインドする必要がある複数の複雑なビュー部分がある場所。このアプローチでは、各子ViewModelのプロパティを持つルートViewModelを構築する必要があります。次に、ルートViewはルートView Modelにバインドされ、各View(表示または折りたたまれているかどうか)はルートViewModelの対応するプロパティにバインドされます。

ViewModelには、次のようになります。

public class RootViewModel 
{ 
    ChildViewModelA ChildA { get; set; } 
    ChildViewModelB ChildB { get; set; } 
} 

ビューは次のようになります。

<Grid> 
    <ChildViewA DataContext="{Binding ChildA}" /> 
    <ChildViewB DataContext="{Binding ChildB}" /> 
</Grid> 

あなたはまた、自身がアクティブなワークスペースを選択することができるように、離れで、これを実装することができます。

ViewModelには、次のようになります。

public class RootViewModel 
{ 
    public List<ViewModel> ChildWorkspaces { get; set; } 
    public ViewModel ActiveWorkspace { get; set; } 

    public RootViewModel() 
    { 
     ChildWorkspaces.Add(ChildViewModelA); 
     ChildWorkspaces.Add(ChildViewModelB); 
    } 
} 

ビューは次のようになります。

<Grid> 
    <Grid.Resources> 
     <DataTemplate DataType="ChildViewModelA"> 
      <ChildViewA /> 
     </DataTemplate> 
     <DataTemplate DataType="ChildViewModelB"> 
      <ChildViewB /> 
     </DataTemplate> 
    </Grid.Resources> 
    <ContentControl Content="{Binding ActiveWorkspace}" /> 
</Grid> 

これは、実際のタイプに基づいて暗黙的に選択された適切な視覚的な表現になりますActiveWorkspaceに格納されているオブジェクト。

私の応答はWPFでした。

「ViewModel」が複数あることがわかるように、あいまいになる可能性があります。多くの場合、ViewModelを適切に構造化するために複数のサブエンティティを構築する必要があります。しかし、すべてのViewModelエンティティは、ルートView Modelオブジェクトのどこかに存在します。

MVVMをWPFで実装する場合、(この応答の後半に示すように)暗黙的にデータコンテキストを適用する視覚的要素を推測することをお勧めします。より複雑なシナリオでは、私はその決定を行うためにDataTemplateSelectorを使用することを好みます。しかし、非常に単純なケースでは、C#/ ActionScriptで明示的にDataContextを適用したり、バインディングを通じて宣言的にDataContextを明示的に適用することができます。

希望すると便利です。

+0

OKので、私はビューがどのビューモデルへの参照が含まれているかどうかわからないし、これは私の混乱をクリアしていると思います最初の例での記述方法です。誰か他の人がコメントしているかどうかを確認するためにこれを数日間開いたままにしておきますが、これは基本的に私が何をしたかです。ありがとう –

+0

ビューがViewModelに持たなければならない唯一の "参照"は、宣言的なバインディングでなければなりません。 MVVMの目標は、ViewとViewModelの両方を互いに無関係にすることです。 – markti

3

私は夫婦別のFlexプロジェクトで使用MVVMアプローチのバリエーションを見てきましたが、私は私に完全に右に感じるのアプローチを見ていません。つまり、プレゼンテーションモデルを使用すると、Flexでのテストがずっと楽になると思います。そのため、このパターンの周りに設計されたアプリケーションが増え始めると確信しています。

FlexでMVVMを実装するのが最も簡単なアプローチは、ViewModelをアプリケーション内に配置することです。Model/ModelLoactorModelLoactorにはすべてのグローバルデータが含まれ、ViewModelsへのアクセサーとしても機能します。 ApplicationViewsは、ModelLocatorを介してその特定のViewModelにバインドできます。一方、ViewModelsは、コマンドとその親のModelLocatorへのバインディングの両方で更新できます。このアプローチの利点の1つは、データロジックのすべてがローカライズされていることです。もちろん、これは欠点として見なすこともでき、ModelLocatorはすべてViewModelsへのハードコーディングされた参照のために脆いです。

私は、Mateフレームワークを使用してよりクリーンなアプローチが動作するのを見てきました。メイトは、適切なApplicationViewsViewModelsのはるかに分散された注射を可能にする。 (私はこれもSwizで達成できると思いますが、私はそのフレームワークに精通していません)。メイトでは、それぞれApplicationViewにはViewModelがマップ経由で注入されています。このアプローチの優れた点は、ViewModelsをEventMap(FrontControllerのMateバージョン)を使用して更新する方法です。基本的にApplicationViewsは、1つまたは複数のEventMapsによって処理されるイベントを送出し、これらのマップはViewModelsの1つ以上に変更を加えることができます。このアプローチでは、ユーザのジェスチャまたはイベントが1つのApplicationViewから一度に複数のViewModelsの状態を変更することができます。さらに、このロジックはMateのEventMapsに抽出されるため、イベントの処理方法や変更されたViewModelsを変更するのは非常に簡単です。もちろん、このアプローチの主な欠点は、Mateをフレームワークとして使用することにコミットしていることです。これはプロジェクトの要件に応じて選択できない場合があります。

私はそれが助けてくれることを願っています!

関連する問題