Utiliser MEF pour importer un Datatatemplate WPF?

je suis à la recherche à la MEF comme un extensibility framework, et je suis assez vendu, sauf pour un point:

disons que je veux importer à la fois un modèle de vue et une vue pour l'afficher. Je pense que la "bonne" façon de le faire est que la partie MEF exporte une classe ViewModel, et un DataTemplate qui affiche le ViewModel. Par exemple, supposons que vous construisiez une application de type Visio et que vous vouliez importer une bibliothèque de formes. Chaque forme nécessite une vue définie dans Xaml et un modèle de vue qui envelopperait un objet modèle sous-jacent.

Est-ce possible? À quoi ressemblerait le contrat D'importation du Dataemplate et comment informer WPF du Dataemplate importé?

24
demandé sur Scott Whitlock 2009-05-09 07:01:13

1 réponses

Oui, j'ai été capable de faire ce travail de la façon suivante:

Dans mon hôte application WPF, j'ai ajouté cette Importation:

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

puis dans ma partie composite, j'ai déclaré un ViewModel, et un modèle de données pour le ViewModel dans un fichier XAML de Ressourcedictioner régulier. Puis j'ai créé un code derrière pour la débrouillardise, comme ceci (dans cet exemple, le ViewModel est appelé ItemViewModel et la débrouillardise est appelée ItemView):

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

Pour de référence, le code Xaml pour l'exemple ResourceDictionary ressemble à ceci:

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

puis, de retour dans mon application hôte WPF, après avoir composé avec succès et avant d'afficher la fenêtre principale, je fais ceci:

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

qui semble appliquer avec succès le Dataemplate partout où WPF voit un item ViewModel.

EDIT: pour quiconque est intéressé, j'ai publié un cadre d'application appelé Soapbox Core comme source ouverte, et il utilise cette méthode permet d'importer largement les vues dans les ressources d'application. Il fonctionne très bien, et vous pouvez télécharger la source vous-même et jetez un oeil à la façon dont il fonctionne.

39
répondu Scott Whitlock 2009-11-07 03:34:48