2009-07-23 13 views
13

Da ich eine Shell-Anwendung und ein paar separates Modul Projekte mit Microsoft CompoisteWPF (Prism v2) haben ...Composite-WPF (Prism) Modul Ressourcendatenvorlagen

Bei Empfang eines Befehls, schafft ein Modul eine neue ViewModel und fügt es über den Regionsmanager einer Region hinzu.

var viewModel = _container.Resolve<IMyViewModel>(); 
_regionManager.Regions[RegionNames.ShellMainRegion].Add(viewModel); 

Ich dachte, dass ich dann ein Ressourcenverzeichnis innerhalb des Moduls erstellen könnte und eine Datenvorlage einrichten eine Ansicht für die Ansicht Modelltyp anzuzeigen, die (unter XAML sehen) geladen wurde. Wenn das Ansichtsmodell jedoch zur Ansicht hinzugefügt wird, wird nur der Namespace der Ansichtsmodelle ausgedruckt.

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:vm="clr-namespace:Modules.Module1.ViewModels" 
    xmlns:vw="clr-namespace:Modules.Module1.Views" 
> 
    <DataTemplate DataType="{x:Type vm:MyViewModel}"> 
     <vw:MyView /> 
    </DataTemplate> 
</ResourceDictionary> 

Edit:

Ich kann es erhalten, indem die Arbeit an den App.xaml Zugabe

<Application.Resources> 
    <ResourceDictionary.MergedDictionaries> 
     <ResourceDictionary Source="pack://application:,,,/Module1;component/Module1Resources.xaml"/> 
     <ResourceDictionary Source="pack://application:,,,/Module2;component/Module2Resources.xaml"/> 
    </ResourceDictionary.MergedDictionaries> 
</Application.Resources> 

was in Ordnung ist, aber es bedeutet, dass neue Module erstellt werden, die App. XAML-Datei muss hinzugefügt werden. Was ich suche ist ein Weg für Module, wie sie geladen werden, um die Application.Resources dynamisch hinzuzufügen. Ist das möglich?

IMergeDictionaryRegistry 
{ 
    void AddDictionaryResource(Uri packUri); 
} 

Sie:

Antwort

5

Innerhalb der Initialisierung jedes Moduls können Sie auf die Anwendungsressourcen hinzufügen:

Application.Current.Resources.MergedDictionaries 
       .Add(new ResourceDictionary 
       { 
        Source = new Uri(
         @"pack://application:,,,/MyApplication.Modules.Module1.Module1Init;component/Resources.xaml") 
       }); 

Oder wenn Sie eine Konvention jedes Moduls folgen hat ein Ressourcenverzeichnis „Resources.xmal“ genannt ...

protected override IModuleCatalog GetModuleCatalog() 
{ 
    var catalog = new ModuleCatalog(); 

    AddModules(catalog, 
       typeof (Module1), 
       typeof(Module2), 
       typeof(Module3), 
       typeof(Module4)); 

    return catalog; 
} 

private static void AddModules(ModuleCatalog moduleCatalog, 
    params Type[] types) 
{ 
    types.ToList() 
     .ForEach(x => 
      { 
       moduleCatalog.AddModule(x); 
       Application.Current.Resources.MergedDictionaries 
        .Add(new ResourceDictionary 
           { 
            Source = new Uri(string.Format(
                 @"pack://application:,,,/{0};component/{1}", 
                 x.Assembly, 
                 "Resources.xaml")) 
           }); 
       }); 
} 
+0

Der erste Teil Ihrer Antwort erfordert, dass Ihr Modul in die Anwendung gelangt. Ich würde das empfehlen, da es nicht überprüfbar ist. Der zweite Ansatz ist angemessener. –

19

Um Ihre Shell-App, die wissen nichts über Ihre Module und Ihre Module erreichen in der Schale in irgendeiner Weise zu vermeiden, würde ich eine Schnittstelle zu Ihrer Module wie diese bieten ‚d für diese Schnittstelle in Ihrem Modulcode fragen:

public class MyModule : IModule 
{ 
    IMergeDictionaryRegistry _merger; 
    public MyModule(IMergeDictionaryRegistry merger) 
    { 
      _merger = merger; 
    } 

    public void Initialize() 
    { 
      _merger.AddDictionaryResource(new Uri("pack://application:,,,/Module1;component/Module1Resources.xaml"); 
    } 
} 

würden Sie dann in Ihrer Shell implementieren dies zu tun:

public MergeDictionaryRegistry : IMergeDictionaryRegistry 
{ 
    public void AddDictionaryResource(Uri packUri) 
    { 
      Application.Current.Resources.MergedDictionaries.Add(new ResourceDictionary() 
      { 
       Source = packUri; 
      }); 
    } 
} 

Und dann schließlich in ConfigureContainer Ihre Bootstrapper ist:

public override void ConfigureContainer() 
{ 
    base.ConfigureContainer(); 
    Container.RegisterType<IMergeDictionaryRegistry, MergeDictionaryRegistry>(); 
} 

Dies wird Ihnen die Funktionalität, die Sie und Ihre Shell und Ihre Module wollen bekommen voneinander unabhängig bleiben. Dies hat den zusätzlichen Vorteil, dass es testbarer ist, da Sie keine Application hochdrehen müssen, um Ihren Modulcode zu testen (nur Schein IMergeDictionaryRegistry und Sie sind fertig).

Lassen Sie uns wissen, wie das für Sie geht.

+0

Danke. WPF kann das ViewModel mithilfe des DataTemplate rendern (siehe: http://msdn.microsoft.com/en-us/magazine/dd419663.aspx#id0090097). Das Problem besteht darin, die App über das DataTemplate in einer anderen Assembly zu informieren. Ich habe den Beitrag bearbeitet, um mehr Details zu liefern. – Oll

+0

Oh ich sehe was du machst. Möglicherweise müssen Sie eine Schnittstelle (IMergeDictionaryRegistration mit einer Methode, die eine Pack-URL akzeptiert) für Ihre Module bereitstellen und sie an das Ressourcenwörterbuch Ihrer Anwendung anhängen. Nur eine Theorie. –

+0

Auch ... Ich bin gespannt, wie das für dich geht. Lass uns wissen. Das ist ein interessanter Ansatz. –

1

Das scheint alles eine Menge Arbeit!

Ich persönlich erklären nur ein Ressourcenverzeichnis in UserControl.Resources Abschnitt meiner Ansicht so ...

<UserControl.Resources> 
    <ResourceDictionary Source="../Resources/MergedResources.xaml" /> 
</UserControl.Resources> 

Das Wörterbuch fusionierte zeigt dann auf alle Ressourcen I umfassen müssen.

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
<ResourceDictionary.MergedDictionaries> 
    <ResourceDictionary Source="Iconography.xaml" /> 
    <ResourceDictionary Source="Typeography.xaml" /> 
</ResourceDictionary.MergedDictionaries> 

würden Sie Ihre Datenvorlagen erklären dort denke ich.

HTH.