2015-09-28 10 views
1

我正尝试用MEF创建一个简单的模块化MVVM应用程序。我有一个ViewModel类和一个UserControl作为视图。我连接两个通过一个DataTemplate,像这样:ViewModel与MEF安装了两次

<DataTemplate DataType="{x:Type local:MyViewModel}"> 
    <local:MyView /> 
</DataTemplate> 

在视图中,我定义的视图模型作为静态资源,作出具有约束力的简单:

<UserControl.Resources> 
    <local:MyViewModel x:Key="ViewModel" /> 
</UserControl.Resources> 

然后我绑定是这样的:

<Grid DataContext="{StaticResource ResourceKey=ViewModel}"> 
    <TextBlock Text="{Binding Text}" /> 
</Grid> 

这一切都按预期工作,没有MEF。然而,正如我瞄准模块化,我使用MEF来发现我的ViewModel类。我有一个属性导出我的ViewModel类:

[Export(typeof(MyViewModel))] 
public class MyViewModel 
{ 
    // ... 
} 

,我使用MEF视图模型动态加载到我的壳在App.xaml.cs:

private void Application_Startup(object sender, StartupEventArgs e) 
{ 
    var shell = new MainWindow(); 
    var catalog = new AssemblyCatalog(this.GetType().Assembly); 
    var container = new CompositionContainer(catalog); 

    shell.Contents.ViewModel = container.GetExportedValues<MyViewModel>().First(); 

    shell.Show(); 
} 

现在,在这一点上,MEF当它加载虚拟机时创建我的ViewModel的一个实例,而我的View在它将虚拟机声明为资源时创建另一个实例。 (这很容易通过在构造函数中设置断点来检查。)

问题是,我应该如何将由MEF创建的实例传递给我的资源声明?我可以将特定实例声明为资源吗?全码

的DropBox链接: https://www.dropbox.com/sh/pbdl029d26sx7gl/AAA6po50dLjbJSoNPBhCyWZ3a?dl=0

+0

修改我的基础结构使用DataContextSpy基于这个答案: http://stackoverflow.com/a/5402653/5219911 让问题开放一下,万一有人提出另一个灵魂,但这似乎现在工作。 –

回答

0

好的,所以,我所要做的就是这样。

我有两个实例,因为一旦MEF在导入它们时实例化ViewModels,然后WPF在创建ViewModel资源时创建它们。我认为解决方案不会直接创建资源,但不知道如何设法做到这一点。然后出现了资源注入,然后DataContextSpy,从这个问题在这里: https://stackoverflow.com/a/5402653/5219911

而这里的直接链接到话题: http://www.codeproject.com/Articles/27432/Artificial-Inheritance-Contexts-in-WPF

我现在用的资源是一个DataContextSpy,通过它我可以接触到创建DataTemplate时使用的ViewModel实例。

在我看来的资源,我定义 然后我刚才设置的根元素的DataContext的这一资源: 的DataContext = “{绑定源= {StaticResource的获取ResourceKey =视图模型}, 路径=的DataContext}”

不幸的是,由于DataContextSpy是真正的DataContext的代理,所以我不能获得Intellisense支持,所以我必须使用以下方法手动设置设计时间DataContext类型: d:DataContext =“ {d:DesignInstance Type = viewModel:MyViewModel}“

0

的MyViewModel的创作纯粹是基于怎样的程序执行的顺序,但你可以把creationPolicy使您的实例成为一个单身这样既代码并且资源都指向相同的实例。

[导出(typeof运算(MyViewModel)),PartCreationPolicy(CreationPolicy.Shared)

边注:要使用MEF,微软隐藏CompositionInitializer和CompositionHost从.Net框架出于某种原因实施。尝试谷歌并从微软导入2类,而不是直接使用CompositionContainer。你将会有更好的使用MEF的经验。

+0

这不幸只告诉MEF实例化我的viewmodel只有一次。问题是,MEF和WPF资源查找都尝试实例化所述视图模型。如果我直接创建视图,我可以添加视图模型资源。但是,由于视图是从DataTemplate创建的,因此我没有对视图的引用来直接访问其资源。 –