Подтвердить что ты не робот

Использование MEF для импорта WPF DataTemplate?

Я смотрел MEF как основу расширяемости, и я почти продан, за исключением одного момента:

Скажем, я хочу импортировать как ViewModel, так и View для его отображения. Я думаю, что "правильный" способ сделать это для части MEF для экспорта класса ViewModel и DataTemplate, который отображает ViewModel. Например, предположим, что вы создаете приложение, подобное Visio, и хотите импортировать библиотеку форм. Каждая форма нуждается в представлении, определенном в Xaml и ViewModel, который обернет некоторый основной объект Model.

Возможно ли это? Как выглядит контракт на импорт для DataTemplate и как мне сделать WPF доступным для импортированного DataTemplate?

4b9b3361

Ответ 1

Да, я смог сделать эту работу следующим образом:

В моем WPF-приложении хоста я добавил этот импорт:

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

Затем в моей составной части я объявил ViewModel и шаблон данных для ViewModel в регулярном файле ResourceDictionary Xaml. Затем я создал код для ResourceDictionary, как это (в этом примере ViewModel называется ItemViewModel, а ResourceDictionary называется ItemView):

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

Для справки, Xaml для примера ResourceDictionary выглядит следующим образом:

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

EDIT. Для всех, кто интересуется, я выпустил фреймворк приложения SoapBox Core как открытый, и он широко использует этот метод для импорта Views в ресурсы приложения. Он работает очень хорошо, и вы можете скачать источник самостоятельно и посмотреть, как он работает.