Domanda

Dato che ho un applicazione guscio e un paio di progetti di moduli separati che utilizzano Microsoft CompoisteWPF (Prisma v2) ...

Alla ricezione di un comando, un modulo crea un nuovo ViewModel e lo aggiunge ad una regione attraverso la regione responsabile.

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

Ho pensato che avrei potuto creare un dizionario risorse all'interno del modulo e impostare un modello di dati per visualizzare una visione per il tipo di vista del modello che è stato caricato (vedi sotto XAML). Ma quando il modello visualizzazione viene aggiunto alla vista, tutto quello che ottiene è lo spazio dei nomi vista modelli stampati.

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

Modifica:

posso farlo funzionare con l'aggiunta al 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>

Il che va bene, ma significa che come vengono creati nuovi moduli, il file App.xaml deve essere aggiunto a. Quello che sto cercando è un modo per i moduli, mentre li carica per aggiungere dinamicamente alle le Application.Resources. È possibile?

È stato utile?

Soluzione 2

Entro l'inizializzazione di ogni modulo, è possibile aggiungere alle risorse dell'applicazione:

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

Se si segue una convenzione di ogni modulo ha un dizionario risorse chiamato "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"))
                              });
              });
}

Altri suggerimenti

Per evitare la shell applicazione di dover sapere nulla circa i vostri moduli e i moduli da raggiungere nel guscio in alcun modo, mi piacerebbe fornire un'interfaccia per i moduli in questo modo:

IMergeDictionaryRegistry
{
     void AddDictionaryResource(Uri packUri);
}

Si potrebbe chiedere di questa interfaccia nel codice del modulo:

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

Si potrebbe quindi implementare questo nella shell per fare questo:

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

E poi finalmente, nel ConfigureContainer del Bootstrapper:

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

Questo ti porterà la funzionalità che si desidera e il tuo Shell e il modulo rimarrà indipendenti l'uno dall'altro. Questo ha il vantaggio di essere più verificabili a che non avete bisogno di girare di un Application per testare il codice del modulo (IMergeDictionaryRegistry solo finto e si è fatto).

Fateci sapere come questo vale anche per te.

Che tutto sembra come un sacco di lavoro!

Personalmente, ho solo dichiaro un dizionario risorse nella sezione UserControl.Resources del mio punto di vista come questo ...

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

Questo dizionario fusione punta poi a tutte le risorse di cui ho bisogno per includere.

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

Si potrebbe dichiarare i modelli di dati in là immagino.

HTH.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top