我正在创建一个mvvm模式的wpf用户控件。 所以我们有:view(代码隐藏文件中没有代码),viewmodel,model,dataaccess文件。
我有 MainWindow .xaml作为视图文件,我需要与 MainWindowModel .cs绑定。
通常,在一个wpf应用程序中,我们可以使用App.xaml文件中的onStartUp事件来完成此操作。但是在用户控制方面,因为我们没有App.xaml ......我如何实现它?
请帮助:( ...提前致谢!!!
答案 0 :(得分:16)
您可以使用ContentControl
和DataTemplate
将UserControl
(查看)绑定到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
名为MainView
而KioskViewModel.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。我发现它是一个很好的资源,虽然它没有解释如何使用用户控件,但你会找到出路。