25

有人可以解释 View 和 ViewModel 是如何连接的吗?我在任何地方都找不到引用 ViewModel 的 View 的 xaml 或 xaml.cs,也找不到引用 View 的 ViewModel.cs 文件中的任何内容,但它们以某种方式连接,并且将 ViewModel 中的成员绑定到 View 工作.

此外,在每个的构造函数中,只有 View 的 InitializeComponent 和 ViewModel 的基本构造函数(没有 View 的声明/定义)。

谢谢!

4

4 回答 4

36

这里有多种选择。

必须将视图设置为ViewModelDataContext的实例。这里有很多选择:

  • 这可以直接在 xaml 中完成(视图只是直接实例化 ViewModel)。
  • 这可以在 View 的构造函数 ( this.DataContext = new MyViewModel();)中完成
  • 这可以通过一个DataTemplate
  • “协调”类可以将它们连接在一起(即:单独的“演示者”类可以构造两者并DataContext适当地设置)

最常见的是让 View 在 xaml 中定义 VM(View-first),或者让所有内容都基于以 ViewModel 为中心的观点,并让 WPF 基于绑定的 VM 自动创建 View(ViewModel-第一的)。

前一种方法是许多工具包使用的方法,例如MVVM Light。后一种方法是我在我的MVVM 博客系列中使用的,并被其他一些工具包使用。

于 2012-06-21T15:40:33.720 回答
5

将视图连接到视图模型的“干净”方式是......

创建视图时,对于每个视图,将其 DataSource 设置为其视图模型:

例如

public class App
{
    private void OnAppStart()
    {
        var model = new MainModel();
        var vm = new MainVM();
        var view = new MainWindow();

        vm.Model = model;
        view.DataSource = vm;

        view.Show();
    }
}

当您查看的模型发生变化时,更新 V​​M:

public class MainVM
{
    private void OnSelectedModelItemChanged()
    {
        this.SelectedItem = new ItemVM();
        this.SelectedItem.Model = this.SelectedModelItem;
    }
}

并使用数据模板使视图为每个 VM 选择正确的子视图。

于 2012-06-21T16:00:52.997 回答
2

视图包含 xaml 中视图模型类的对象。

InitializeComponent 函数创建页面上的所有控件、设置样式等。

于 2012-06-21T15:39:48.080 回答
1

正如其他人已经表明的那样,有多种选择。当然,每当您听到多种选择时,您都必须想知道每种选择的优点和缺点是什么。好吧,事实证明,除了一个之外,它们都有主要的缺点。

以下方法不涉及外部库,没有额外的管理类和接口,几乎没有魔法,并且非常灵活,因为您可以拥有包含其他视图模型的视图模型,并且您可以实例化它们中的每一个,因此您可以将构造函数参数传递给他们。

对于主窗口的视图模型:

using Wpf = System.Windows;

public partial class TestApp : Wpf.Application
{
    protected override void OnStartup( Wpf.StartupEventArgs e )
    {
        base.OnStartup( e );
        MainWindow = new MainView();
        MainWindow.DataContext = new MainViewModel( e.Args );
        MainWindow.Show();
    }
}

对于所有其他视图模型:

这是在 MainViewModel.cs 中:

using Collections = System.Collections.Generic;

public class MainViewModel
{
    public SomeViewModel SomeViewModel { get; }
    public OtherViewModel OtherViewModel { get; }
    public Collections.IReadOnlyList<string> Arguments { get; }
    
    public MainViewModel( Collections.IReadOnlyList<string> arguments )
    {
        Arguments = arguments;
        SomeViewModel = new SomeViewModel( this );
        OtherViewModel = new OtherViewModel( this );
    }
}

这在 MainView.xaml 中:

[...]
xmlns:local="clr-namespace:the-namespace-of-my-wpf-stuff"
[...]
    <local:SomeView DataContext="{Binding SomeViewModel}" />
    <local:OtherView DataContext="{Binding OtherViewModel}" />
[...]

如您所见,视图模型可以简单地成为另一个视图模型的成员(子);在这种情况下,SomeViewModel 和 OtherViewModel 是 MainViewModel 的子项。然后,在 MainView 的 XAML 文件中,您可以只实例化每个子视图并将其指定DataContextBinding相应的子视图模型。

于 2020-08-05T17:09:12.687 回答