有人可以解释 View 和 ViewModel 是如何连接的吗?我在任何地方都找不到引用 ViewModel 的 View 的 xaml 或 xaml.cs,也找不到引用 View 的 ViewModel.cs 文件中的任何内容,但它们以某种方式连接,并且将 ViewModel 中的成员绑定到 View 工作.
此外,在每个的构造函数中,只有 View 的 InitializeComponent 和 ViewModel 的基本构造函数(没有 View 的声明/定义)。
谢谢!
这里有多种选择。
必须将视图设置为ViewModelDataContext
的实例。这里有很多选择:
this.DataContext = new MyViewModel();
)中完成DataTemplate
DataContext
适当地设置)最常见的是让 View 在 xaml 中定义 VM(View-first),或者让所有内容都基于以 ViewModel 为中心的观点,并让 WPF 基于绑定的 VM 自动创建 View(ViewModel-第一的)。
前一种方法是许多工具包使用的方法,例如MVVM Light。后一种方法是我在我的MVVM 博客系列中使用的,并被其他一些工具包使用。
将视图连接到视图模型的“干净”方式是......
创建视图时,对于每个视图,将其 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();
}
}
当您查看的模型发生变化时,更新 VM:
public class MainVM
{
private void OnSelectedModelItemChanged()
{
this.SelectedItem = new ItemVM();
this.SelectedItem.Model = this.SelectedModelItem;
}
}
并使用数据模板使视图为每个 VM 选择正确的子视图。
视图包含 xaml 中视图模型类的对象。
InitializeComponent 函数创建页面上的所有控件、设置样式等。
正如其他人已经表明的那样,有多种选择。当然,每当您听到多种选择时,您都必须想知道每种选择的优点和缺点是什么。好吧,事实证明,除了一个之外,它们都有主要的缺点。
以下方法不涉及外部库,没有额外的管理类和接口,几乎没有魔法,并且非常灵活,因为您可以拥有包含其他视图模型的视图模型,并且您可以实例化它们中的每一个,因此您可以将构造函数参数传递给他们。
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 文件中,您可以只实例化每个子视图并将其指定DataContext
给Binding
相应的子视图模型。