2009-05-09 16 views
24

Patrzyłem na MEF jako ramy rozszerzeń, i jestem prawie sprzedany, z wyjątkiem jednego punktu:Używanie MEF do importowania danych WPF DataTemplate?

Powiedzmy, że chcę zaimportować zarówno ViewModel i View, aby go wyświetlić. Myślę, że "właściwym" sposobem jest to, aby część MEF wyeksportowała klasę ViewModel i DataTemplate, która wyświetla ViewModel. Jako przykład powiedzmy, że tworzyłeś aplikację podobną do Visio i chcesz zaimportować bibliotekę kształtów. Każdy kształt potrzebuje Widoku zdefiniowanego w Xaml i ViewModelu, który otoczyłby jakiś bazowy obiekt Modelu.

Czy to możliwe? Jak wyglądałaby umowa importowa dla DataTemplate i jak uczynić WPF świadomym zaimportowanego DataTemplate?

Odpowiedz

39

Tak, byłem w stanie wykonać tej pracy w następujący sposób:

W mojej aplikacji hosta WPF, dodałem tego importu:

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

Wtedy w moim kompozytowej części I ogłoszony ViewModel oraz szablon danych dla ViewModel w zwykłym pliku Xaml ResourceDictionary. Potem stworzył kod tyłu za ResourceDictionary, jak to (w tym przykładzie ViewModel nazywa ItemViewModel i ResourceDictionary nazywa ItemView):

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

Dla porównania, XAML dla przykładu ResourceDictionary wygląda następująco:

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

Następnie z powrotem w mojej aplikacji hosta WPF, po tym, jak z powodzeniem komponować i zanim pokażę okno główne, robię to:

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

Wydaje się, że z powodzeniem stosuje się DataTemplate w dowolnym miejscu, w którym WPF widzi ItemViewModel.

EDIT: Dla każdego, kto jest zainteresowany, wydałem ramy aplikacji nazwie SoapBox Core jako open source, i to w znacznym stopniu korzysta z tej metody importowania Wyświetleń do zasobów aplikacji. Działa bardzo dobrze, możesz sam pobrać źródło i sprawdzić, jak działa.

+0

Próbowałem tego dokładnego podejścia, ale ResourceDictionary jest pusty w czasie ładowania. Czy istnieje sposób na wymuszenie inicjalizacji lub czy robię coś złego? –

Powiązane problemy