2009-07-23 14 views
13

यह देखते हुए कि मैं एक खोल आवेदन और माइक्रोसॉफ्ट CompoisteWPF (प्रिज्म v2) का उपयोग कर अलग मॉड्यूल परियोजनाओं के एक जोड़े है ...समग्र WPF (प्रिज्म) मॉड्यूल संसाधन डेटा टेम्पलेट्स

एक आदेश प्राप्त होने पर एक मॉड्यूल एक नया बनाता है ViewModel और क्षेत्र प्रबंधक के माध्यम से इसे एक क्षेत्र में जोड़ता है।

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

मैंने सोचा था कि मैं तो मॉड्यूल के भीतर एक संसाधन शब्दकोश बना सकते हैं और देखने मॉडल प्रकार है कि लोड किया गया था के लिए एक दृश्य प्रदर्शित करने के लिए एक डेटा टेम्पलेट की स्थापना (XAML नीचे देखें)। लेकिन जब दृश्य मॉडल को दृश्य में जोड़ा जाता है, तो मुझे लगता है कि दृश्य मॉडल नामस्थान मुद्रित है।

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

संपादित करें:

मैं इसे 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> 

कौन सा ठीक है को जोड़कर काम करने के लिए प्राप्त कर सकते हैं, लेकिन इसका मतलब है कि नए रूप में मॉड्यूल बनाई गई हैं, अनुप्रयोग। xaml फ़ाइल को जोड़ने की जरूरत है। जो मैं खोज रहा हूं वह मॉड्यूल के लिए एक तरीका है, क्योंकि वे गतिशील रूप से एप्लिकेशन में जोड़ते हैं। स्रोत। क्या यह संभव है?

उत्तर

5

प्रत्येक मॉड्यूल के initialisation के भीतर, आप आवेदन संसाधनों के लिए जोड़ सकते हैं:

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

या यदि आप का पालन प्रत्येक मॉड्यूल के एक सम्मेलन में एक संसाधन शब्दकोश "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

आपके उत्तर के पहले भाग की आवश्यकता है कि आपका मॉड्यूल एप्लिकेशन में पहुंच जाए। मैं इसके खिलाफ सिफारिश करता हूं क्योंकि यह अवांछनीय है। दूसरा दृष्टिकोण अधिक उपयुक्त है। –

19

अपने मॉड्यूल और किसी भी तरह से खोल में बाहर तक पहुँचने से अपने मॉड्यूल के बारे में कुछ भी पता होने से अपने खोल एप्लिकेशन बचने के लिए, मैं इस तरह अपने मॉड्यूल के लिए एक इंटरफेस प्रदान चाहते हैं:

IMergeDictionaryRegistry 
{ 
    void AddDictionaryResource(Uri packUri); 
} 

आप अपने मॉड्यूल कोड में इस इंटरफेस के लिए 'पूछना चाहूंगी:

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

फिर आप यह करने के लिए अपने खोल में यह लागू होगा:

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

और फिर अंत में, अपने Bootstrapper के ConfigureContainer में:

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

यह आपको आप चाहते हैं और अपने शेल और अपने मॉड्यूल एक दूसरे से स्वतंत्र रहेगा कार्यक्षमता मिल जाएगा। इसमें आपके परीक्षण कोड का परीक्षण करने के लिए Application को स्पिन करने की आवश्यकता नहीं है (केवल IMergeDictionaryRegistry और आप कर चुके हैं) में अधिक टेस्टेबल होने का अतिरिक्त लाभ है।

हमें बताएं कि यह आपके लिए कैसे जाता है।

+0

धन्यवाद। WPF जानता DataTemplate का उपयोग करके ViewModel रेंडर करने के लिए कैसे (देखें: http://msdn.microsoft.com/en-us/magazine/dd419663.aspx#id0090097)। मुद्दा ऐप को किसी अन्य असेंबली में DataTemplate के बारे में जानने के लिए मिल रहा है। मैंने अधिक जानकारी प्रदान करने के लिए पोस्ट संपादित किया है। – Oll

+0

ओह, मैं देख रहा हूं कि आप क्या कर रहे हैं। आपको अपने मॉड्यूल में कुछ इंटरफ़ेस (IMergeDictionaryRegistration w/एक विधि जो एक पैक यूआरएल स्वीकार करता है) प्रदान करना पड़ सकता है और उन्हें अपने एप्लिकेशन के संसाधन शब्दकोश में जोड़ना पड़ सकता है। बस एक सिद्धांत। –

+0

इसके अलावा ... मैं उत्सुक हूं कि यह आपके लिए कैसे जाता है। हमें बताऐ। यह एक दिलचस्प दृष्टिकोण है। –

1

यह सब बहुत काम की तरह लगता है!

व्यक्तिगत रूप से, मैं तो बस मेरे विचार के UserControl.Resources अनुभाग इस तरह के ऐसे संसाधन शब्दकोश घोषित ...

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

यही तो शब्दकोश विलय कर किसी भी संसाधन मैं शामिल करने की जरूरत की ओर इशारा करता।

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

आप मुझे लगता है कि में अपने डेटा टेम्पलेट्स की घोषणा होगी।

एचटीएच।

संबंधित मुद्दे