2009-07-23 4 views
13

Dato che ho un applicazione guscio e un paio di progetti di moduli separati che utilizzano Microsoft CompoisteWPF (Prisma v2) ...Composite WPF (Prism) risorse modulo modelli di dati

Alla ricezione di un comando, un modulo crea un nuovo ViewModel e lo aggiunge a una regione tramite il manager della regione.

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 di vista viene aggiunto alla vista, tutto quello che ottengo è il namespace dei modelli di vista stampato.

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

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> 

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

risposta

5

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

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

Oppure, 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")) 
           }); 
       }); 
} 
+0

La prima parte della risposta richiede che il modulo raggiunga l'applicazione. Consiglierei contro questo perché non è testabile. Il secondo approccio è più appropriato. –

19

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 forniscono un'interfaccia per i moduli in questo modo:

IMergeDictionaryRegistry 
{ 
    void AddDictionaryResource(Uri packUri); 
} 

È 'd chiedere per 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 programma di avvio automatico:

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

questo modo si ottiene la funzionalità che si desidera e vostra Shell e il modulo rimarrà indipendenti l'uno dall'altro. Questo ha l'ulteriore vantaggio di essere più testabile in quanto non è necessario ruotare uno Application per testare il codice del modulo (basta prendere in giro IMergeDictionaryRegistry e il gioco è fatto).

Facci sapere come va questo per te.

+0

Grazie. WPF sa come rendere ViewModel usando DataTemplate (vedi: http://msdn.microsoft.com/en-us/magazine/dd419663.aspx#id0090097). Il problema è far conoscere l'app su DataTemplate in un altro assembly. Ho modificato il post per fornire maggiori dettagli. – Oll

+0

Oh capisco cosa stai facendo. Potrebbe essere necessario fornire un'interfaccia (IMergeDictionaryRegistration w/un metodo che accetta un URL del pacchetto) ai moduli e aggiungerli al dizionario delle risorse dell'applicazione. Solo una teoria. –

+0

Inoltre ... sono curioso di sapere come va questo per te. Facci sapere. Questo è un approccio interessante. –

1

Sembra tutto un bel po 'di lavoro!

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

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

in cui sono confluiti dizionario quindi punti a tutte le risorse che ho bisogno di 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> 

Faresti dichiarare i modelli di dati in là immagino.

HTH.