如何在MVVM模式中加载wpf usercontrol
我正在创建一个采用mvvm模式的wpf用户控件。 所以我们有:视图(代码隐藏文件中没有代码)、视图模型、模型、数据访问文件 我有MainWindow.xaml作为一个视图文件,我需要用MainWindowModel.cs绑定它 通常,在wpf应用程序中,我们可以使用App.xaml文件中的onStartUp事件来完成此操作。但在用户控制中,由于我们没有App.xaml…我如何实现它如何在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
请帮助:(…提前感谢!!!您可以使用
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设计模式,因此我会有一个基本视图模型类,提供有用的功能,例如实现essentialINotifyPropertyChanged
接口。然后,在类型为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>