Question

Étant donné que j'ai une application shell et un couple de projets de modules séparés à l'aide de Microsoft CompoisteWPF (Prism v2) ...

Sur réception d'une commande, un module crée une nouvelle ViewModel et il ajoute à une région par le gestionnaire de la région.

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

Je pensais que je pourrais alors créer un dictionnaire de ressources dans le module et mettre en place un modèle de données pour afficher une vue pour le type de modèle de vue qui a été chargé (voir ci-dessous XAML). Mais lorsque le modèle de vue est ajoutée à la vue, tout ce que je reçois est la vue namespace modèles imprimés.

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

Je peux l'obtenir pour travailler en ajoutant au App.xaml

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

Ce qui est bien, mais cela signifie que de nouveaux modules sont créés, le fichier App.xaml doit être ajouté à. Ce que je suis à la recherche est un moyen pour les modules, car ils se chargent d'ajouter dynamiquement aux Application.Resources les. Est-ce possible?

Était-ce utile?

La solution 2

Dans l'initialisation de chaque module, vous pouvez ajouter aux ressources de l'application:

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

Ou si vous suivez une convention de chaque module dispose d'un dictionnaire de ressources appelé « 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"))
                              });
              });
}

Autres conseils

Pour éviter que votre application shell d'avoir à connaître quoi que ce soit au sujet de vos modules et vos modules de qui tend vers la coquille de quelque façon, je voudrais fournir une interface à vos modules comme ceci:

IMergeDictionaryRegistry
{
     void AddDictionaryResource(Uri packUri);
}

Vous poseriez cette interface dans votre code du module:

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

Vous pouvez ensuite mettre en œuvre dans votre shell pour faire ceci:

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

Et puis enfin, dans le ConfigureContainer de votre Bootstrapper:

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

vous obtiendrez la fonctionnalité que vous voulez et votre Shell et votre module restera indépendant de l'autre. Cela a l'avantage d'être plus testable que vous avez pas besoin de tourner en place un Application pour tester votre code module (IMergeDictionaryRegistry juste maquette et vous avez terminé).

Faites-nous savoir comment cela va pour vous.

tout cela ressemble à beaucoup de travail!

Personnellement, je viens de déclarer un dictionnaire de ressources dans la section UserControl.Resources de moi comme ça ...

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

Ce dictionnaire fusionné indique alors à toutes les ressources dont j'ai besoin d'inclure.

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

Vous souhaitez déclarer vos modèles de données là-bas je suppose.

HTH.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top