我有一个 WPF 应用程序,它使用 MVVM 实现导航,填充不同的 DataTemplate
对于同一 Window
中的每个 View 例如:
<Window.Resources>
<DataTemplate DataType="{x:Type foo:FooViewModel}">
<foo:FooView/>
</DataTemplate>
<DataTemplate DataType="{x:Type bar:BarViewModel}">
<bar:BarView/>
</DataTemplate>
<Window.Resources>
(Switching between Views/UserControls using MVVM 是 Rachel Lim 的文章,它启发了上述方法)
现在发生的事情是 FooView 将 FooViewModel 作为依赖项自动注入(inject) DI(在我的情况下是 Microsoft.Extensions.DependencyInjection on .Net Core3 Preview),例如:
public partial class FooView : UserControl
{
public FooView(FooViewModel fooViewModel)
{
this.InitializeComponent();
this.DataContext = fooViewModel;
}
}
此时显然 DataTemplate 提示,因为 FooView 没有定义无参数的ctor(根据引用 Type '{0}' is not usable as an object element )
有没有办法绕过这个问题,让 FooView 使用 FooViewModel 作为 DataContext?
最佳答案
数据模板
<DataTemplate DataType="{x:Type foo:FooViewModel}">
<foo:FooView/>
</DataTemplate>
将 FooViewModel 的实例分配给 FooView.DataContext。
this.DataContext = fooViewModel;
输入 FooView
控制是无用的,因为在这种情况下 DataContext 将被覆盖。我想说,不通过 contrustor 传递 View 模型是完全可以的。可以从 DataContext 访问它:public partial class FooView : UserControl
{
public FooView()
{
this.InitializeComponent();
}
private FooViewModel Vm { get { return this.DataContext as FooViewModel; } }
}
在您使用的导航模式中,View 是 ViewModel 的接收器。当前 ViewModel 由
AppViewModel
设置:public class AppViewModel
{
// simplified properties
public ViewModelBase CurrentViewModel {get; set;}
public ICommand ViewFooCommand {get;}
public ICommand ViewBarCommand {get;}
}
您正试图让 View 成为 ViewModel 的发起者/生产者,这与模式冲突。
关于wpf - 如何将 DataTemplate 数据类型绑定(bind)到接收 ViewModels DI 注入(inject)的依赖项的 View,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57521629/