2010-05-20 60 views
6

我正在创建一个wvf用户控件,它是mvvm模式。 所以我们有:view(代码隐藏文件中没有代码),viewmodel,model,dataaccess文件。如何在MVVM模式中加载wpf usercontrol

我有主窗口的.xaml作为视图文件,这是我需要与MainWindowModel的.cs结合。

通常,在一个wpf应用程序中,我们可以使用App.xaml文件中的onStartUp事件来做到这一点。但在用户控制中,因为我们没有App.xaml ...我如何实现它?

请帮助:(...先谢谢了!

回答

16

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

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

... 

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

WPF会根据Content

+0

我们不需要任何属性(依赖属性或普通属性)...在内容标签中?或者“当前”如何满足相同的内容? – Relativity 2010-05-20 12:47:58

+0

嗨托马斯,你能给我一个关于上述查询的想法吗? – Relativity 2010-05-21 06:15:56

+1

在上面的代码中,“Current”将是数据上下文的属性,类型为“MyViewModel” – 2010-05-21 09:22:00

2

自动选择DataTemplate我一直在使用MVVM Light Toolkit它有一个ViewModelLocator类,你可以把道具ERTIES在的ViewModels然后你在你的Mainwindow.xaml创建于ViewModelLocator的参考,像这样:

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

在网格面板,或者你使用,你就可以这样设置的DataContext什么:

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

你也可以去MEFedMVVM在能够交换不同的视图模型实现到视图方面潜在地增加了更多的灵活性。

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

2

有无数的方法来做到这一点,它们都属于两种类别之一:“先查看”或“先模型”。

在“视图第一”模式下的视图(例如,您的主窗口)创建,然后再(例如,在代码隐藏)视图实例化视图模型,并将它作为其的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,看看他们是如何做到的。

+0

谢谢..我会看看它 – Relativity 2010-05-20 10:16:05

+0

随意标记你喜欢的答案作为接受的答案。 – bitbonk 2010-05-20 10:48:22

+0

在MVVM模型中,我们可以在代码后面的代码中使用代码吗? – Relativity 2010-05-20 10:50:44

0

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

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

反正有做使用的DataTemplate

5

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

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

由此,不需要在任何地方设置DataContext。

UPDATE >>>

针对@Vignesh Natraj的要求,这里是一个更全面的解释:

一旦你在Resources元素建立DataTemplate,你可以在这个例子中显示KioskView通过在您的XAML中的任何位置添加KioskViewModel的实例。这可能是填充MainWindow,或者只是在屏幕的特定部分。您还可以在ListBox中托管KioskViewModel的多个实例,并且它将生成多个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> 

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

例如,在绑定到MainViewMainViewModel.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> 

注意,在这个例子中,我们需要声明两个(或更多,以使这种方法很有用)DataTemplate S IN的App.xaml文件:

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

你能解释一下我是如何工作的吗?我试过这个,但是没有任何东西被我的观点束缚。 我知道它的旧但感谢。 – 2013-03-01 09:38:33

0

你也许可以看看MSDN。我觉得它是一个很好的资源,虽然它没有解释如何使用usercontrols,但你会发现你的出路。