如何在MVVM模式中加载wpf usercontrol

如何在MVVM模式中加载wpf usercontrol,wpf,mvvm,user-controls,Wpf,Mvvm,User Controls,我正在创建一个采用mvvm模式的wpf用户控件。 所以我们有:视图(代码隐藏文件中没有代码)、视图模型、模型、数据访问文件 我有MainWindow.xaml作为一个视图文件,我需要用MainWindowModel.cs绑定它 通常,在wpf应用程序中,我们可以使用App.xaml文件中的onStartUp事件来完成此操作。但在用户控制中,由于我们没有App.xaml…我如何实现它 请帮助:(…提前感谢!!!您可以使用ContentControl和DataTemplate将UserControl

我正在创建一个采用mvvm模式的wpf用户控件。 所以我们有:视图(代码隐藏文件中没有代码)、视图模型、模型、数据访问文件

我有MainWindow.xaml作为一个视图文件,我需要用MainWindowModel.cs绑定它

通常,在wpf应用程序中,我们可以使用App.xaml文件中的onStartUp事件来完成此操作。但在用户控制中,由于我们没有App.xaml…我如何实现它


请帮助:(…提前感谢!!!

您可以使用
ContentControl
DataTemplate
UserControl
(视图)绑定到视图模型:

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

...

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

...
WPF将根据我一直使用的
内容的类型自动选择
数据模板

,该内容有一个ViewModelLocator类,您可以将属性放入其中。然后在Mainwindow.xaml中创建对ViewModelLocator的引用,如下所示:

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

在“网格”面板或您正在使用的任何工具中,可以如下设置datacontext:

<Grid DataContext="{Binding MainWindowViewModel, Source={StaticResource Locator}}">
...
</Grid>
<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>

...
您还可以使用它,在能够将不同的viewModel实现交换到视图中方面,它可能会增加一点灵活性


这两个库的灵活性在于,如果您不想使用它们的ViewModel基类,则不必使用它们的ViewModel基类—ViewModelLocator和MEFedMVVM可以与任何类一起使用。

有无数种方法可以做到这一点,它们都属于两类之一:“视图优先”或“模型优先”

在“视图优先”模式下,首先创建视图(例如主窗口),然后(例如在代码隐藏中)视图实例化ViewModel并将其设置为datacontext:

在“模型优先”模式下,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();    
}
这里给出的例子只是众多例子中的一种。您可以查看各种方法并了解它们是如何实现的。

我们可以使用它们在对象内部调用方法。如下所示:

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


使用DataTemplate是否也可以这样做?我知道这是一个老问题,但我有不同的方法。我喜欢在App.xaml文件中建立隐式关系:

<Application.Resources>
    <DataTemplate DataType="{x:Type ViewModels:KioskViewModel}">
        <Views:KioskView />
    </DataTemplate>
</Application.Resources>
我更喜欢在WPF中使用MVVM设计模式,因此我会有一个基本视图模型类,提供有用的功能,例如实现essential
INotifyPropertyChanged
接口。然后,在类型为
BaseViewModel
的主(顶级)视图模型中有一个名为
ViewModel
的属性。这为我提供了一种很好的方法,可以将
ViewModel
属性更改为从
BaseViewModel
派生的任何视图模型,从而能够从视图模型更改关联视图

例如,在绑定到
MainView
MainViewModel.cs
类中,有一个字段和相关属性:

private BaseViewModel viewModel = new KioskViewModel();
public BaseViewModel ViewModel
{
    get { return viewModel; }
    set { viewModel = value; NotifyPropertyChanged("ViewModel"); }
}
如您所见,它以一个
KioskViewModel
实例开始,但可以随时更改为任何其他视图以响应用户交互。对于这个设置,XAML非常类似,但是我们没有在
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>

你可以看看。我发现它是一个很好的资源,虽然它没有解释如何使用usercontrols,但您会找到解决方法。

在MVVM模型中,我们可以在视图的代码隐藏文件中使用代码吗?是的!许多实现都使用codebehind将视图与viewmodel连接起来。为了可混合性和可测试性,这应该保持在最低限度。我们不需要任何属性(依赖属性或普通属性)…在内容标签中?…或者“当前”如何满足相同的要求?嗨,托马斯,你能给我一个关于上述查询的想法吗?在上面的代码中,
Current
将是数据上下文的属性,类型为
MyViewModel
它会初始化类“MyViewModel”的实例吗?另外…ContentControl是否知道它必须引用哪个数据模板?否,它创建了MyUserControl的实例。创建MyViewModel的实例是您的责任。ContentControl从参考资料中选取DataTemplate:它查找与ViewModel具有相同数据类型且没有x:Key属性的DataTemplate。如果您能解释这是如何工作的,我尝试了这一点,但没有任何内容绑定到我的视图。我知道它很旧,但是谢谢。
<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>
<Application.Resources>
    <DataTemplate DataType="{x:Type ViewModels:MainViewModel}">
        <Views:MainView />
    </DataTemplate>
    <DataTemplate DataType="{x:Type ViewModels:KioskViewModel}">
        <Views:KioskView />
    </DataTemplate>
</Application.Resources>