2009-05-09 7 views
24

Ich betrachtete MEF als Erweiterbarkeit Framework, und ich bin ziemlich viel verkauft, mit Ausnahme eines Punkts:Verwenden von MEF zum Importieren eines WPF DataTemplate?

Angenommen, ich möchte sowohl ein ViewModel und eine Ansicht importieren, um es anzuzeigen. Ich denke, der "richtige" Weg dahin besteht darin, dass der MEF-Teil eine ViewModel-Klasse exportiert und eine DataTemplate, die das ViewModel anzeigt. Angenommen, Sie erstellen eine Visio-ähnliche Anwendung und möchten eine Bibliothek mit Formen importieren. Jede Form benötigt eine in Xaml definierte Ansicht und ein ViewModel, das ein zugrunde liegendes Model-Objekt umschließt.

Ist das möglich? Wie würde der Importvertrag für das DataTemplate aussehen und wie mache ich WPF auf das importierte DataTemplate aufmerksam?

Antwort

39

Ja, ich war in der Lage, diese Arbeit in der folgenden Art und Weise zu machen:

In meinem Gast WPF-Anwendung, ich diesen Import hinzugefügt:

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

Da ist in meinem Verbundteil, erklärte ich ein Ansichtsmodell und eine Datenvorlage für das ViewModel in einer regulären ResourceDictionary Xaml-Datei. Dann habe ich einen Code hinter der Resource, wie folgt aus (in diesem Beispiel wird das Ansichtsmodell genannt ItemViewModel und das Resource wird ItemView genannt):

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

Als Referenz XAML für das Beispiel Resource wie folgt aussieht:

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

Dann zurück in meinem Gast WPF-Anwendung, nachdem ich erfolgreich zusammensetzen und bevor ich das Hauptfenster zeigen, ich dies tun:

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

Das scheint das DataTemplate überall erfolgreich anzuwenden. WPF sieht ein ItemViewModel.

EDIT: Für jeden, der interessiert ist, veröffentlichte ich eine Framework-Anwendung SoapBox Core als Open Source genannt, und es verwendet diese Methode ausführlich Ansichten in die Anwendungsressourcen zu importieren. Es funktioniert sehr gut und Sie können die Quelle selbst herunterladen und schauen, wie es funktioniert.

+0

Ich habe diesen genauen Ansatz versucht, aber das ResourceDictionary ist zur Ladezeit leer. Gibt es eine Möglichkeit, die Initialisierung zu erzwingen oder mache ich etwas falsch? –

Verwandte Themen