Pregunta

Dado que tengo una aplicación de shell y un par de proyectos de módulo por separado utilizando Microsoft CompoisteWPF (Prisma v2) ...

Al recibir un comando, un módulo crea un nuevo modelo de vista y lo añade a una región a través del gestor región.

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

pensé que entonces podría crear un diccionario de recursos dentro del módulo y establecer un modelo de datos para mostrar una vista para el tipo de vista de modelo que se cargó (ver más abajo xaml). Pero cuando se añade el modelo de vista a la vista, lo único que consigue es la vista los modelos de espacio de nombre impreso.

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

Editar:

puedo conseguir que funcione mediante la adición a la 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>

Lo que está bien, pero significa que a medida que se crean nuevos módulos, el archivo App.xaml necesita ser añadido a. Lo que estoy buscando es una forma de módulos, ya que se cargan dinámicamente para agregar a los los Application.Resources. ¿Es esto posible?

¿Fue útil?

Solución 2

Dentro de la inicialización de cada módulo, se pueden añadir a los recursos de la aplicación:

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

O si usted sigue una convención de cada módulo tiene un diccionario de recursos denominado "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"))
                              });
              });
}

Otros consejos

Para evitar que su aplicación cáscara de tener que saber nada acerca de sus módulos y los módulos de llegar en la cáscara de ninguna manera, me proporciona una interfaz para los módulos de la siguiente manera:

IMergeDictionaryRegistry
{
     void AddDictionaryResource(Uri packUri);
}

pediría esta interfaz en el código del módulo:

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

A continuación, poner en práctica esta en la shell para hacer esto:

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

Y, por último, en ConfigureContainer de su programa previo:

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

Esto le dará la funcionalidad que desea y su Shell y su módulo seguirá siendo independiente el uno del otro. Esto tiene la ventaja añadida de ser más comprobable en que no tiene necesidad de girar una Application para probar el código del módulo (IMergeDictionaryRegistry simplemente maqueta y ya está).

Háganos saber cómo esto va para ti.

Todo eso parece como un montón de trabajo!

En lo personal, me declaro un diccionario de recursos en la sección UserControl.Resources de mi vista como esta ...

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

Eso diccionario fusionada después señala a cualquier recurso que necesito incluir.

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

Se podría declarar las plantillas de datos ahí supongo.

HTH.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top