C# 视图如何知道在WPF中使用哪个ViewModel?
有人能解释一下视图和视图模型是如何连接的吗?我在任何地方都找不到引用ViewModel的视图的xaml或xaml.cs,也找不到引用视图的ViewModel.cs文件中的任何内容,但是它们以某种方式连接在一起,并且可以将成员从ViewModel绑定到视图 此外,在每个视图的构造函数中,只有视图的InitializeComponent和ViewModel的基本构造函数(没有视图的声明/定义)C# 视图如何知道在WPF中使用哪个ViewModel?,c#,wpf,mvvm,C#,Wpf,Mvvm,有人能解释一下视图和视图模型是如何连接的吗?我在任何地方都找不到引用ViewModel的视图的xaml或xaml.cs,也找不到引用视图的ViewModel.cs文件中的任何内容,但是它们以某种方式连接在一起,并且可以将成员从ViewModel绑定到视图 此外,在每个视图的构造函数中,只有视图的InitializeComponent和ViewModel的基本构造函数(没有视图的声明/定义) 谢谢 视图包含xaml中视图模型类的对象 InitializeComponent函数创建页面上的所有控件,
谢谢 视图包含xaml中视图模型类的对象
InitializeComponent函数创建页面上的所有控件,设置样式等。这里有各种选项 必须将视图的
DataContext
设置为ViewModel的实例。这里有很多选择:
- 这可以直接在xaml中完成(视图只是直接引用ViewModel)李>
- 这可以在视图的构造函数中完成(
)This.DataContext=new MyViewModel();
- 这可以通过
DataTemplate
- “协调”类可以将它们连接在一起(即:一个单独的“presenter”类可以同时构造这两个类并适当地设置
)DataContext
public class MainVM
{
private void OnSelectedModelItemChanged()
{
this.SelectedItem = new ItemVM();
this.SelectedItem.Model = this.SelectedModelItem;
}
}
并使用数据模板使view为每个VM选择正确的子视图。正如其他人已经显示的,有多个选项。当然,每当你听到多种选择时,你都会想知道每种选择的优缺点是什么。事实证明,除了一个以外,它们都有很大的缺点 下面的方法不涉及外部库,不涉及额外的内务管理类和接口,几乎没有魔法,而且非常灵活,因为您可以拥有包含其他ViewModel的viewmodels,并且可以实例化其中的每一个,这样您就可以将构造函数参数传递给它们 对于主窗口的viewmodel: 对于所有其他viewmodels: 这在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 );
}
}
使用集合=System.Collections.Generic;
公共类主视图模型
{
公共SomeViewModel SomeViewModel{get;}
公共OtherViewModel OtherViewModel{get;}
public Collections.IReadOnlyList参数{get;}
public MainViewModel(Collections.IReadOnlyList参数)
{
参数=参数;
SomeViewModel=新的SomeViewModel(此);
OtherViewModel=新的OtherViewModel(此);
}
}
这在MainView.xaml中:
[...]
xmlns:local="clr-namespace:the-namespace-of-my-wpf-stuff"
[...]
<local:SomeView DataContext="{Binding SomeViewModel}" />
<local:OtherView DataContext="{Binding OtherViewModel}" />
[...]
[…]
xmlns:local=“clr名称空间:我的wpf内容的名称空间”
[...]
[...]
如您所见,viewmodel可以只是另一个viewmodel的成员(子级);在本例中,SomeViewModel和OtherViewModel是MainViewModel的子对象。然后,在MainView的XAML文件中,您可以实例化每个子视图,并通过
绑定到相应的子视图模型来指定它们的DataContext
。它会在哪里?我找不到任何包含单词“ViewModel”(这就是我的视图模型的名称)的文本。您可能需要查看Reed的回答。我这样做的方式是在视图的xaml中有一个viewmodel的对象。由于不清楚您是否使用了第三方MVVM框架,我怀疑您需要发布一些代码才能得到准确的答案。你可以用几十种不同的方式连接视图和视图模型,但我们看不到你面前有什么代码。我建议回到基础上来——我写了一个关于MVVM的系列文章,其中涵盖了一些基础知识,比如“什么是视图模型”和“什么是视图”以及它们是如何连接在一起的。可能值得略读:+1。这种“协调”类通常称为Controller
(MVC模式)或Presenter
(MVP模式),其中Presenter同时充当控制器和视图模型。走向MVP将意味着视图模型将打开视图。@OlivierJacot Descombes,除非您使用数据模板,否则虚拟机确实需要打开视图。@DannyVarod如果您使用数据模板,WPF将有效地成为MVP术语中的“演示者”,为您协调这一点。然而,它将成为基于反射的通用演示者。@ReedCopsey谢谢!我找到了它所在的位置,它被嵌入到某个地方,这个地方调用了一些设置DataContext的东西。(虽然不是我会做的…)ViewModel已创建,然后在EventHandler中定义为视图的DataContext:s
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 );
}
}
[...]
xmlns:local="clr-namespace:the-namespace-of-my-wpf-stuff"
[...]
<local:SomeView DataContext="{Binding SomeViewModel}" />
<local:OtherView DataContext="{Binding OtherViewModel}" />
[...]