使用MEF导入WPF DataTemplate?

24

我正在研究MEF作为一个可扩展框架,基本上已经决定使用了,唯一的问题是:

假设我想导入一个ViewModel和一个View来显示它。 我认为“正确”的做法是,MEF部分应该导出一个ViewModel类和一个DataTemplate来显示ViewModel。 例如,假设您正在构建类似于Visio的应用程序,并且想要导入一组形状库。 每个形状需要在Xaml中定义一个View和包装某些基础Model对象的ViewModel。

这可行吗? DataTemplate的导入契约会是什么样子?如何让WPF意识到已导入的DataTemplate?

1个回答

40

是的,我成功地按照以下方式实现了这个功能:

在我的宿主WPF应用程序中,我添加了此导入:

    [ImportMany("ApplicationResources", typeof(ResourceDictionary))]
    public IEnumerable<ResourceDictionary> Views { get; set; }

在我的组合部分中,我声明了一个ViewModel和一个数据模板,用于在常规的ResourceDictionary Xaml文件中为该ViewModel定义。然后,我为ResourceDictionary创建了一个代码后备,如下所示(在此示例中,ViewModel称为ItemViewModel,ResourceDictionary称为ItemView):

[Export("ApplicationResources", typeof(ResourceDictionary))]
public partial class ItemView : ResourceDictionary 
{
    public ItemView()
    {
        InitializeComponent();
    }
}

参考示例,此 ResourceDictionary 的 Xaml 如下:

<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:MyCompany.MyProduct"
    x:Class="MyCompany.MyProduct.ItemView">

    <DataTemplate DataType="{x:Type local:ItemViewModel}">
        ...
    </DataTemplate>

</ResourceDictionary>

然后,在我的主机WPF应用程序中,成功组合并显示主窗口之前,我执行以下操作:

// Add the imported resource dictionaries
// to the application resources
foreach (ResourceDictionary r in Views)
{
    this.Resources.MergedDictionaries.Add(r);
}

这似乎成功地将DataTemplate应用于WPF在任何地方看到ItemViewModel的情况。

编辑:对于任何感兴趣的人,我发布了一个名为SoapBox Core的应用程序框架作为开源软件,并且广泛使用此方法将视图导入应用程序资源中。它运行得非常好,您可以自己下载源代码并查看其工作方式。


我尝试了这种方法,但在加载时ResourceDictionary为空。有没有一种方法可以强制初始化或者是我做错了什么? - Brian Triplett

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接