c# - WPF MVVM 为什么使用 ContentControl + DataTemplate View 而不是直接的 XAML 窗口 View ?

标签 c# wpf xaml mvvm architecture

为什么会这样?

主窗口.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:(设置启动窗口/ View )

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

本质上是“作为数据模板查看”(VaD) 与“作为窗口查看”(VaW)

这是我对比较的理解:

  • VaD:让您无需关闭窗口即可切换 View 。 (这对我的项目来说是不可取的)
  • VaD:VM 对 View 一无所知,而在 VaW 中,它(仅)必须能够在打开另一个窗口时实例化它
  • VaW:我实际上可以看到我的 xaml 在设计器中呈现(我看不到 使用 VaD,至少在我当前的设置中)
  • VaW:直观地与 打开和关闭 window ;每个窗口都有(是)一个相应的 View (和 View 模型)
  • VaD:ViewModel 可以通过属性传递初始窗口宽度、高度、可调整大小等(而在 VaW 中,它们直接在窗口中设置)
  • VaW:可以设置 FocusManager.FocusedElement(不确定在 VaD 中如何设置)
  • VaW:文件更少,因为我的窗口类型(例如功能区、对话框)已合并到它们的 View 中

那么这里发生了什么?我不能只在 XAML 中构建我的窗口,通过 VM 的属性干净地访问它们的数据,然后完成它吗?代码隐藏是相同的(几乎为零)。

我很难理解为什么我应该将所有 View 内容混入 ResourceDictionary。

最佳答案

当人们想要根据 ViewModel 动态切换 View 时,他们会以这种方式使用 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.DataContextVM1的一个实例,那么View1会被显示,

如果

Window.DataContextVM2的一个实例,那么View2就会显示出来。

诚然,如果只期望 1 个 View 且从未更改,则根本没有任何意义。

关于c# - WPF MVVM 为什么使用 ContentControl + DataTemplate View 而不是直接的 XAML 窗口 View ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19864891/

相关文章:

c# - 为什么后台垃圾收集有时会暂停我的应用程序,我该如何防止它发生?

布局之间项目的 WPF 动画?

wpf - 需要知道混合吗?

c# - 如何使用 SslStream 类禁用加密?

c# - 后台任务 UWP Windows 10 中的 Websockets

c# - 使用 .NET 创建磁盘镜像

wpf - 如何在 WindowStyle ="None"的 WPF 窗口中强制执行 MinWidth 和 MinHeight?

c# - 将 ResourceDictionary 复制到 C# 中的字典

c# - 学习 WPF 会提高我的 ASP.NET 技能吗?

c# - Windows 通用应用程序实时加速度计数据图表