WPF Prism - Where to put Resources?

2019-03-09 21:52发布

问题:

I have a prism application and various modules. I am wondering where is the best place to locate resources such as styles, brush, controltemplates, datatemplates?

Should I make one single resource dictionary and put everything there? Should each module have their own resources? Or each view? I would like to follow the Prism goal of keeping everything modular, but also I dont see the point in re-declaring the same resources in every module...

回答1:

I develop application with Prism, and I use technique very close to described in Prism's manual. There is YourApplication.Infrastructure project, where you usually place all your shared interfaces etc. So:

  1. I just add project YourApplication.Resources
  2. Create there folder Themes
  3. Create separate xaml file in Themes folder for each group of resources (like Generic.WPF.xaml for standard WPF controls' styles, Generic.Brushes.xaml for brushes etc.)
  4. Create file Themes\Generic.xaml (exactly with this name, it will add huge benefits in the future) with content like

    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    
        <ResourceDictionary.MergedDictionaries>
    
            <ResourceDictionary Source="Generic.Brushes.xaml"/>
            <ResourceDictionary Source="Generic.WPF.xaml"/>
    
        </ResourceDictionary.MergedDictionaries>
    
    </ResourceDictionary>
    
  5. Now you can add those resources in any module (you have separate project for it, right?) by adding reference to YourApplication.Resources to that project and adding to your view's xaml:

    <UserControl.Resources>
        <ResourceDictionary>
    
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/YourApplication.Resources;component/Themes/Generic.xaml"/>
            </ResourceDictionary.MergedDictionaries>
    
            <!-- Put your not shared resource here -->
    
        </ResourceDictionary>
    </UserControl.Resources>
    

I don't know, maybe this way has some problems, but it works, and works well for me. If anybody can comment somehow this way (pros/cons) - I will be very happy to hear it!



回答2:

Application-wide resources I usually put in a ResourceDictionary, which is added to either App.xaml or StartupWindow.xaml

Resources for a specific View are usually located with the View. For example, a UserControl that is being used for a CalendarView will contain any custom resources for the Calendar, such as calendar-specific brushes, styles, templates, etc.

I usually don't see a reason to make module-wide resources, but if I ever do I'd have a ResourceDictionary for the Module which can be loaded into the app's merged dictionaries at runtime, or included in individual Views in the Module.



回答3:

I would like to share some new knowledges. I am using @chopikadze approach. And it is really cool approach. Thanks to you!

However, if you do not want write every time for each control these piece of code:

<UserControl.Resources>
    <ResourceDictionary>    
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="pack://application:,,,/YourApplication.Resources;component/Themes/Generic.xaml"/>
        </ResourceDictionary.MergedDictionaries>    
        <!-- Put your not shared resource here -->    
    </ResourceDictionary>
</UserControl.Resources>

Then you can just declare <ResourceDictionary/> in App.xaml of your Bootstrapper like that:

<Application.Resources>        
    <ResourceDictionary Source="pack://application:,,,/YourApplication.Resources;component/Themes/Generic.xaml"/>
</Application.Resources>


标签: c# wpf Prism