如何在MVVM模式中加载wpf usercontrol

时间:2010-05-20 08:40:20

标签: wpf mvvm user-controls

我正在创建一个mvvm模式的wpf用户控件。 所以我们有:view(代码隐藏文件中没有代码),viewmodel,model,dataaccess文件。

我有 MainWindow .xaml作为视图文件,我需要与 MainWindowModel .cs绑定。

通常,在一个wpf应用程序中,我们可以使用App.xaml文件中的onStartUp事件来完成此操作。但是在用户控制方面,因为我们没有App.xaml ......我如何实现它?

请帮助:( ...提前致谢!!!

6 个答案:

答案 0 :(得分:16)

您可以使用ContentControlDataTemplateUserControl(查看)绑定到ViewModel:

<DataTemplate DataType="{x:Type vm:MyViewModel}">
    <v:MyUserControl />
</DataTemplate>

...

<ContentControl Content="{Binding Current}" />

WPF会根据DataTemplate

的类型自动选择Content

答案 1 :(得分:5)

我知道这是一个陈旧但回答的问题,但我有不同的方法。我喜欢在App.xaml文件中建立隐式关系:

<Application.Resources>
    <DataTemplate DataType="{x:Type ViewModels:KioskViewModel}">
        <Views:KioskView />
    </DataTemplate>
</Application.Resources>

有了这个,就不需要在任何地方设置DataContext。

更新&gt;&gt;&gt;

回应@Vignesh Natraj的要求,这是一个更全面的解释:

DataTemplate元素中设置Resources之后,您可以通过在XAML中的任意位置添加KioskView的实例来显示此示例中的KioskViewModel 。这可能会填充MainWindow,或者只是填充屏幕的特定部分。您还可以在KioskViewModel中托管ListBox的多个实例,它将生成多个KioskView个实例。

您可以通过多种方式将KioskViewModel的实例添加到XAML中,具体取决于您的要求。一种方法是为包含KioskViewModel.cs文件的项目声明XML命名空间,只需在ContentControl中将其实例添加到您希望显示视图的页面中。例如,如果您有UserControl名为MainViewKioskViewModel.cs文件位于Kiosk.ViewModels名称空间中,则可以使用基本的XAML:

<UserControl x:Class="Kiosk.Views.MainView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:ViewModels="clr-namespace:Kiosk.ViewModels">
    <UserControl.Resources>
        <ViewModels:KioskViewModel x:Key="KioskViewModel" />
        <DataTemplate DataType="{x:Type ViewModels:KioskViewModel}">
            <Views:KioskView />
        </DataTemplate>
    </UserControl.Resources>
    <ContentControl Content="{StaticResource KioskViewModel}" />
</UserControl>

我更喜欢将MVVM设计模式与WPF一起使用,因此我将有一个基本视图模型类,提供有用的功能,例如实现基本的INotifyPropertyChanged接口。然后,我在类型ViewModel的主(顶级)视图模型中有一个名为BaseViewModel的属性。这为我提供了一种很好的方法,可以将ViewModel属性更改为派生自BaseViewModel的任何视图模型,从而能够从视图模型中更改关联的视图。

例如,在绑定到MainViewModel.cs的{​​{1}}类中,有一个字段和相关属性:

MainView

如您所见,它以private BaseViewModel viewModel = new KioskViewModel(); public BaseViewModel ViewModel { get { return viewModel; } set { viewModel = value; NotifyPropertyChanged("ViewModel"); } } 实例开始,但可以随时更改为任何其他视图以响应用户交互。对于此设置,XAML非常相似,但不是在KioskViewModel元素中声明视图模型的实例,而是绑定到Resources中的属性:

MainViewModel

请注意,对于此示例,我们需要在<UserControl x:Class="Kiosk.Views.MainView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ViewModels="clr-namespace:Kiosk.ViewModels"> <ContentControl Content="{Binding ViewModel}" /> </UserControl> 文件中声明两个(或更多以使此方法有用)DataTemplate

App.xaml

答案 2 :(得分:2)

我一直在使用MVVM Light Toolkit,它有一个ViewModelLocator类,您可以将属性放入viewmodel中。然后在Mainwindow.xaml中创建对ViewModelLocator的引用,如下所示:

<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True"/>

在网格面板或您正在使用的任何内容中,您可以像这样设置datacontext:

<Grid DataContext="{Binding MainWindowViewModel, Source={StaticResource Locator}}">
...
</Grid>

你也可以使用MEFedMVVM,这可以在将不同的viewModel实现交换到视图方面增加更多的灵活性。

这两个库的灵活性在于,如果您不想使用ViewModelLocator和MEFedMVVM,则不必使用ViewModel基类。

答案 3 :(得分:2)

有无数的方法可以做到这一点,所有这些都属于以下两个类别中的一个:“先看”或“先看模特”。

在“查看第一个”模式中,首先创建视图(例如,您的主窗口),然后(例如在代码隐藏中)View实例化ViewModel并将其设置为其datacontext):

private void WindowLoaded(object sender, EventArgs args)
{
   this.DataContext = ViewModelService.GetViewModelX();
}

在“模型优先”模式中,ViewModel首先存在,然后实现视图。

// method of the viewmodel 
public void LoadView()
{
     // in this example the view abstracted using an interface
     this.View = ViewService.GetViewX();
     this.View.SetDataContext(this);
     this.View.Show();    
}

这里给出的例子只是众多的一种方式。您可以查看各种MVVM frameworks,看看他们是如何做到的。

答案 4 :(得分:0)

我们可以使用ObjectDataProvider来调用对象内的方法..如下:

<ObjectDataProvider ObjectType="{x:Type local:TemperatureScale}"
                    MethodName="ConvertTemp" 
                    x:Key="convertTemp">

无论如何都要使用DataTemplate

来做同样的事情

答案 5 :(得分:0)

您可以查看MSDN。我发现它是一个很好的资源,虽然它没有解释如何使用用户控件,但你会找到出路。