首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >WPF MVVM为什么使用ContentControl + DataTemplate视图而不是直接的XAML窗口视图?

WPF MVVM为什么使用ContentControl + DataTemplate视图而不是直接的XAML窗口视图?
EN

Stack Overflow用户
提问于 2013-11-09 01:18:54
回答 3查看 88.5K关注 0票数 88

为什么这样?

MainWindow.xaml:

代码语言:javascript
复制
<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设置为:

代码语言:javascript
复制
<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>

创建窗口,如下所示:

代码语言:javascript
复制
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:(设置启动窗口/视图)

代码语言:javascript
复制
<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)

代码语言:javascript
复制
<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)与.“以窗口方式查看”(VaW)

以下是我对这种比较的理解:

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

那么这是怎么回事呢?难道我不能只在XAML中构建我的窗口,通过VM的属性干净地访问它们的数据,然后就完成了吗?代码隐藏是相同的(实际上是零)。

我很难理解为什么我要把所有的视图东西都放到一个ResourceDictionary中。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-11-09 01:26:34

当人们想要根据ViewModel动态切换视图时,就会以这种方式使用DataTemplates

代码语言:javascript
复制
<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

诚然,如果只期望一个视图,并且从未更改,这是没有任何意义的。

票数 137
EN

Stack Overflow用户

发布于 2014-11-04 17:17:35

由于在VaD中视图模型对视图一无所知,因此您可以构建一个完全由视图模型而不是视图组成的全功能应用程序。这导致了编写完全由代码驱动的应用程序的可能性。这反过来导致了在没有GUI的情况下执行集成测试的可能性。通过GUI进行的集成测试是出了名的脆弱--而通过视图模型进行的测试应该更健壮。

票数 8
EN

Stack Overflow用户

发布于 2013-11-09 01:44:34

根据我的个人经验:这两种工作模式都是可用的,这取决于你想要什么,也取决于应用程序的需求。VaD背后的想法是解码内容和容器。如果实现了VaD,那么无论何时显示任何这种类型的项目,都可以使用这个模板(默认情况下)。您可以在ItemsControls (列表、列表视图、网格等)中使用它,也可以只在ContentControls中进行绑定。就像你说的,VaD用于切换窗口的内容,而不需要关闭和打开一个新的。您还可以使用UserControls定义视图,然后您可以控制聚焦的元素,还可以在后台管理代码。因此,您的数据模板可能如下所示:

代码语言:javascript
复制
<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都是可以的。实际上,您可以同时使用VaWVaD。最后一个可以用于应用程序的内部项目,不需要windows。你选择对你更好的,取决于应用程序的需求,以及开发应用程序所需的时间。希望这段亲身经历能对你有所帮助。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19864891

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档