使用 MEF 导入 WPF DataTemplate?

发布于 2024-07-18 11:28:34 字数 311 浏览 2 评论 0原文

我一直将 MEF 视为一个可扩展性框架,除了一点之外,我几乎被说服了:

假设我想导入一个 ViewModel 和一个 View 来显示它。 我认为“正确”的方法是让 MEF 部分导出 ViewModel 类和显示 ViewModel 的 DataTemplate。 举个例子,假设您正在构建一个类似 Visio 的应用程序,并且想要导入形状库。 每个形状都需要一个在 Xaml 中定义的视图和一个包装某些底层模型对象的 ViewModel。

这可能吗? DataTemplate 的导入协定是什么样的?如何让 WPF 了解导入的 DataTemplate?

I was looking at MEF as an extensibility framework, and I'm pretty much sold, except for one point:

Let's say I want to import both a ViewModel and a View to display it. I think the "right" way to do that is for the MEF part to export a ViewModel class, and a DataTemplate that displays the ViewModel. As an example, say you were building a Visio-like application and you want to import a library of shapes. Each shape needs a View defined in Xaml and a ViewModel that would wrap some underlying Model object.

Is this possible? What would the Import contract look like for the DataTemplate and how do I make WPF aware of the imported DataTemplate?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

未蓝澄海的烟 2024-07-25 11:28:34

是的,我能够通过以下方式完成这项工作:

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

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

然后在我的复合部分中,我在常规 ResourceDictionary Xaml 文件中声明了一个 ViewModel 以及该 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 的开源应用程序框架,它广泛使用这种方法将视图导入到应用程序资源中。 它运行得很好,你可以自己下载源码并看看它是如何运行的。

Yes, I was able to make this work in the following way:

In my host WPF application, I added this Import:

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

Then in my composite part, I declared a ViewModel, and a data template for the ViewModel in a regular ResourceDictionary Xaml file. Then I created a code behind for the ResourceDictionary, like this (in this example, the ViewModel is called ItemViewModel and the ResourceDictionary is called ItemView):

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

For reference, the Xaml for the example ResourceDictionary looks like this:

<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>

Then, back in my host WPF application, after I successfully compose and before I show the main window, I do this:

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

That seems to successfully apply the DataTemplate anywhere WPF sees an ItemViewModel.

EDIT: For anyone who's interested, I released an application framework called SoapBox Core as open source, and it uses this method extensively to import Views into the application resources. It works very well, and you can download the source yourself and take a look at how it works.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文