WPF复合Windows和ViewModels

时间:2011-05-31 18:37:18

标签: c# .net wpf data-binding mvvm

我有一个WPF Window,其中包含很少UserControls,这些控件包含另一个。现在,如何为此窗口创建ViewModel以及在何处绑定它的最主要方法是什么。

我确实希望首先为每个子控件创建ViewModel

4 个答案:

答案 0 :(得分:4)

有几种方法可以做到这一点。

注入VM

我会推荐这种方法。

如果您的窗口是在App类中创建的,例如

var window = new MyWindow();
window.Show();

我会在显示窗口之前分配VM:

var window = new MyWindow();
window.DataContext = GetDataContextForWindow();
window.Show();

如果您的某个控件需要自己的视图模型,请分配VM wile创建控件实例。

的DataBind

如果要设置控件的VM,可以将DataContext属性绑定到周围VM提供的VM实例。

<Controls:MyControl DataContext={Binding MyControlsVm} />

代码背后

您可以在后面的代码中使用init方法设置VM,如

public MyWindow()
{
    InitializeComponent();
    DataContext = CreateViewModel;
}

如果您不想为主页创建VM,则可以使用技巧:

public MyWindow()
{
    InitializeComponent();
    DataContext = this;
}

只需将类后面的代码用作VM。

答案 1 :(得分:1)

我将视图视为ViewModel的可视化表示,因此我喜欢WPF根据它想要呈现的ViewModel实例选择视图。

我称之为View Locator模式,我使用this method 来实例化我的视图,因为我发现它实现起来非常简单。

它基本上会在您的应用的ResourceDictionary中添加一个条目,该条目告诉WPF使用IValueConverter查找并View ViewModel遇到<Application x:Class="MyApp.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="MainWindow.xaml" > <Application.Resources> <ResourceDictionary Source="Resources.xaml"/> </Application.Resources> </Application>

所以一个有效的例子是:

在app.xaml中:

<DataTemplate DataType="{x:Type vm:ViewModelBase}">
    <ContentControl Content="{Binding Converter={StaticResource ViewModelConverter}}"/>
</DataTemplate>

在resources.xaml:

DataContext

设置启动窗口控制的public MainWindow : Window { InitializeComponent(); DataContext = new MainViewModel(); } ,例如

MainViewModel

你已经完成了很多工作。所以,如果您有public class MainViewModel : ViewModelBase { public ChildViewModel1 Child1 {get;set;} public ChildViewModel2 Child2 {get;set;} } 这样的话:

UserControl

你有一个MainViewModel可以解析为你的<UserControl x:Class="MainView"> <StackPanel> <ContentPresenter Content="{Binding Child1}"/> <ContentPresenter Content="{Binding Child2}"/> </StackPanel> </UserControl>

ViewModelConverter

因此,您的{{1}}将返回相应视图的实例,而无需您做任何额外的努力。

答案 2 :(得分:0)

在子控件问题上,为什么根视图模型的其中一个属性不是您传递给子控件的子视图模型的实例?另一个选项是转换器,它将基于非视图模型的属性转换为子视图模型的实例(如适配器模式)。

答案 3 :(得分:-1)

您可能对 WPF Application Framework (WAF) 的示例应用感兴趣。它们展示了如何实例化复合视图和视图模型以及它们如何相互影响。