WPF MVVM 为什么使用 ContentControl + DataTemplate 视图而不是直接的 XAML 窗口视图? [英] WPF MVVM Why use ContentControl + DataTemplate Views rather than straight XAML Window Views?

查看:20
本文介绍了WPF MVVM 为什么使用 ContentControl + DataTemplate 视图而不是直接的 XAML 窗口视图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么会这样?

MainWindow.xaml:

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 设置为:

Have your ExampleView.xaml set up as:

<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:(设置启动窗口/视图)

App.xaml: (Set startup window/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)

ExampleView.xaml: (a Window not a 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)

以下是我对比较的理解:

Here is my understanding of the comparison:

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

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

So what's going on here? Can't I just build my windows in XAML, access their data cleanly through properties of the VM, and be done with it? The code-behind is the same (virtually nil).

我一直在努力理解为什么我应该将所有 View 内容改组到 ResourceDictionary 中.

I'm struggling to understand why I should shuffle all the View stuff into a ResourceDictionary.

推荐答案

人们在想要根据 ViewModel 动态切换视图时使用 DataTemplates :

People use DataTemplates that way when they want to dynamically switch Views depending on the ViewModel:

<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

if Window.DataContext is an instance of VM1, then View1 will be displayed,

如果

Window.DataContextVM2 的一个实例,然后会显示View2.

Window.DataContext is an instance of VM2, then View2 will be displayed.

当然,如果只需要 1 个视图并且永远不会改变,那完全没有意义.

Granted, it makes no sense at all if only 1 View is expected, and never changed.

这篇关于WPF MVVM 为什么使用 ContentControl + DataTemplate 视图而不是直接的 XAML 窗口视图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆