2009-05-09 15 views
24

Estaba buscando MEF como un marco de extensibilidad, y estoy prácticamente vendido, excepto por un punto:¿Utiliza MEF para importar un WPF DataTemplate?

Digamos que quiero importar un ViewModel y una View para mostrarlo. Creo que la forma "correcta" de hacerlo es que la parte MEF exporte una clase ViewModel y una DataTemplate que muestre ViewModel. Como ejemplo, supongamos que está creando una aplicación similar a Visio y desea importar una biblioteca de formas. Cada forma necesita una vista definida en Xaml y un modelo de vista que envolvería algún objeto modelo subyacente.

¿Esto es posible? ¿Cómo se vería el contrato de importación para DataTemplate y cómo hago que WPF conozca el DataTemplate importado?

Respuesta

39

Sí, yo era capaz de hacer este trabajo de la siguiente manera:

En mi anfitrión aplicación de WPF, que añade esta importación:

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

Luego, en mi pieza de material compuesto, que declararon un modelo de vista y una plantilla de datos para ViewModel en un archivo ResourceDictionary Xaml regular. Entonces creé un código detrás de la ResourceDictionary, como esto (en este ejemplo, el modelo de vista se llama ItemViewModel y la ResourceDictionary se llama ItemView):

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

Como referencia, el XAML para el ejemplo ResourceDictionary se parece a esto:

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

Luego, de vuelta en mi host de la aplicación WPF, después compongo con éxito y antes de que yo muestro la ventana principal, hago esto:

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

Parece que se aplica con éxito DataTemplate en cualquier lugar donde WPF vea un ItemViewModel.

EDITAR: Para cualquiera que esté interesado, que libera un marco de aplicación llamada fuente SoapBox Core tan abierto, y utiliza este método ampliamente para importar Vistas en los recursos de la aplicación. Funciona muy bien, y puede descargar la fuente usted mismo y echar un vistazo a cómo funciona.

+0

Intenté este enfoque exacto pero el ResourceDictionary está vacío en el momento de la carga. ¿Hay alguna manera de forzar la inicialización o estoy haciendo algo mal? –

Cuestiones relacionadas