1. ホーム
  2. c#

[解決済み] WPF MVVM XAML Window Viewsではなく、ContentControl + DataTemplate Viewsを使用する理由とは?

2023-04-06 01:13:48

疑問点

なぜこのようなことをするのですか?

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です。(ResourceDictionaryではなくWindow)

<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>


基本的にそれは View as DataTemplate" (VaD) vs. "View as Window" (VaW)です。

以下は、この比較に関する私の理解です。

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

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

なぜすべてのビューのものを ResourceDictionary にシャッフルしなければならないのか、理解に苦しんでいます。

どのように解決するのですか?

人々は DataTemplates を使うことがあります。

<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 のインスタンスである場合 VM2 であれば View2 が表示されます。

もし、1つのViewだけが期待され、決して変更されないとしたら、それは全く意味がありません。