WPF MVVMなぜストレートXAMLウィンドウビューではなく、ContentControl + DataTemplateビューを使用するのですか?


83

なぜこれ?

MainWindow.xaml:

<Window x:Class="MVVMProject.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <ContentControl Content="{Binding}"/>
    </Grid>
</Window>

ExampleView.xamlを次のように設定します。

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:vms="clr-namespace:MVVMProject.ViewModels">
    <DataTemplate DataType="{x:Type vms:ExampleVM}" >
        <Grid>
            <ActualContent/>
        </Grid>
    </DataTemplate>
</ResourceDictionary>

そして、次のようなウィンドウを作成します。

public partial class App : Application {

    protected override void OnStartup(StartupEventArgs e) {

        base.OnStartup(e);

        MainWindow app = new MainWindow();
        ExampleVM context = new ExampleVM();
        app.DataContext = context;
        app.Show();
    }
}

このようにできるのはいつですか?

App.xaml :(起動ウィンドウ/ビューの設定)

<Application x:Class="MVVMProject.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    StartupUri="ExampleView.xaml">
</Application>

ExampleView.xaml :(リソース辞書ではないウィンドウ)

<Window x:Class="MVVMProject.ExampleView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:vms="clr-namespace:MVVMProject.ViewModels">
    >
    <Window.DataContext>
        <vms:ExampleVM />
    </Window.DataContext>

    <Grid>
        <ActualContent/>
    </Grid>
</Window>

基本的には、「DataTemplateとして表示」(VaD)と「ウィンドウとして表示」(VaW)です。

これが比較についての私の理解です:

  • VaD:ウィンドウを閉じずにビューを切り替えることができます。(これは私のプロジェクトには望ましくありません)
  • VaD:VMはビューについてまったく何も知りませんが、VaWでは、別のウィンドウを開くときにVMをインスタンス化できる必要があります(のみ)
  • VaW:デザイナーでレンダリングされたxamlを実際に見ることができます(少なくとも現在のセットアップでは、VaDでは表示できません)
  • VaW:ウィンドウの開閉を直感的に操作できます。各ウィンドウには、対応するビュー(およびViewModel)があります。
  • VaD:ViewModelは、プロパティを介して初期ウィンドウの幅、高さ、サイズ変更可能性などを渡すことができます(VaWではウィンドウに直接設定されます)
  • VaW:FocusManager.FocusedElementを設定できます(VaDでの方法はわかりません)
  • VaW:ウィンドウタイプ(リボン、ダイアログなど)がビューに組み込まれているため、ファイルが少なくなります

では、ここで何が起こっているのでしょうか。XAMLでウィンドウを構築し、VMのプロパティを介してデータにクリーンにアクセスし、それを実行することはできませんか?コードビハインドは同じです(事実上ゼロ)。

すべてのViewのものをResourceDictionaryにシャッフルする必要がある理由を理解するのに苦労しています。


2
次のように考えてください。ViewModelsはWindowsまたはUserControlsのいずれかに表示されます。PocoはDataTemplatesに表示されます。:)
開発ハリネズミ

回答:


129

DataTemplatesViewModelに応じてビューを動的に切り替えたい場合は、この方法を使用します。

<Window>
    <Window.Resources>
       <DataTemplate DataType="{x:Type local:VM1}">
          <!-- View 1 Here -->
       </DataTemplate>

       <DataTemplate DataType="{x:Type local:VM2}">
          <!-- View 2 here -->
       </DataTemplate>
    </Window.Resources>

    <ContentPresenter Content="{Binding}"/>

</Window>

そう、

場合Window.DataContextのインスタンスであるVM1場合、View1表示されます、

で、もし

Window.DataContextはのインスタンスでありVM2View2が表示されます。

確かに、1つのビューのみが期待され、変更されない場合は、まったく意味がありません。


8

VaDでは、ビューモデルはビューについて何も認識しないため、ビューモデルのみで完全に構成され、ビューがない完全に機能するアプリケーションを構築できます。これにより、完全にコードで駆動できるアプリケーションを作成できる可能性があります。これにより、GUIなしで統合テストを実行できるようになります。GUIを介した統合テストは脆弱であることがよく知られていますが、ビューモデルを介したテストはより堅牢である必要があります。


5

私の個人的な経験から:どちらの作業モデルも、必要なものとアプリケーションの要件に応じて、実行可能です。背後にVaDある考え方は、コンテンツとコンテナをデコッピングすることです。実装VaDすると、このタイプのアイテムを表示するときにいつでもこのテンプレートを使用できます(デフォルト)。これはItemsControls(リスト、リストビュー、グリッドなど)で使用ContentControlsでき、バインディングの作成でのみ使用できます。あなたが言ったようにVaD、新しいウィンドウを閉じたり開いたりせずにウィンドウのコンテンツを切り替えるために機能します。また、を使用してビューを定義し、UserControlsフォーカスされた要素かどうかを制御できます。また、コードビハインドを管理することもできます。したがって、データテンプレートは次のようになります。

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vms="clr-namespace:MVVMProject.ViewModels">
<DataTemplate DataType="{x:Type vms:ExampleVM}" >
    <CustomUserControl A="{Binding A}" B="{Binding B}" DataContext="{Binding}" .../>
</DataTemplate>

また、UserControl依存関係のプロパティを設定することもできます。これにより、アプリのバインドと分離が可能になるため、作業が簡単になります。

ただし、もちろん、アプリが動的にコンテンツを切り替える必要がない場合VaWは、メインウィンドウやその他のウィンドウに使用しても問題ありません。実際、との両方VaWを使用できますVaD。この最後のものは、ウィンドウを必要としないアプリの内部アイテムに使用できます。アプリケーションの要件と、アプリの開発に利用できる時間に応じて、自分にとってより良いものを選択します。この個人的な経験がお役に立てば幸いです...

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.