Frage

Da ich eine Shell-Anwendung und ein paar separaten Modul Projekte mit Microsoft CompoisteWPF (Prism v2) habe ...

Bei Empfang eines Befehls, ein Modul erstellt ein neues Ansichtsmodell und fügt sie in eine Region durch die Region Manager.

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 geladen wurde (unter XAML sehen). Aber wenn das View-Modell zur Ansicht hinzugefügt wird, alles, was ich bekommen ist der Ansicht Modelle Namensraum 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 auf die App.xaml an der Arbeit durch Hinzufügen

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

das ist in Ordnung, aber es bedeutet, dass neuer Module erstellt werden, die App.xaml-Datei hinzugefügt werden muss. Was ich suche ist eine Möglichkeit für Module, wie sie laden, um sich dynamisch an die die Application.Resources hinzuzufügen. Ist das möglich?

War es hilfreich?

Lösung 2

Im Rahmen 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 jeden Moduls folgen hat ein Ressourcenverzeichnis namens „Resources.xmal“ ...

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"))
                              });
              });
}

Andere Tipps

Ihre Shell-App Um zu vermeiden, die etwas über Ihre Module und Ihre Module zu wissen, erreicht heraus in die Schale in irgendeiner Weise, würde ich eine Schnittstelle zu Ihrer Module wie folgt liefern:

IMergeDictionaryRegistry
{
     void AddDictionaryResource(Uri packUri);
}

Sie würden in Ihrem Modulcode für diese Schnittstelle 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");
     }
}

Sie würden dann implementieren diese in Ihrer Shell, 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 Ihrem Bootstrapper des ConfigureContainer:

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

Diese erhalten Sie die Funktionen, die Sie wollen und Ihre Shell und Ihre Module werden voneinander unabhängig bleiben. Dies hat den zusätzlichen Vorteil, dass mehr prüfbar, dass Sie keine Notwendigkeit, einen Application Spin bis zu Ihrem Modul Code zu testen (nur Mock IMergeDictionaryRegistry und fertig).

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

Das alles scheint wie eine Menge Arbeit!

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

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

Das fusionierte Wörterbuch zeigt dann auf alle Ressourcen, ich brauche aufzunehmen.

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

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

HTH.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top