GrayFox
GrayFox

Reputation: 1089

ResourceDictionary in WPF UserControl library doesn't work

I create an UserControl library in wpf and want to define some general styles. So I've added an global.xaml:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:system="clr-namespace:System;assembly=mscorlib">

    <system:String x:Key="DefaultSearchImage">
        pack://application:,,,/WPF_Controls;component/Images/Search.png
    </system:String>
</ResourceDictionary>

I want to avoid this

<UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="../Styles/Globals.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</UserControl.Resources>

in every user control for performance reasons. So I've found one solution at this site:

Using Shared Resourec via static Dictionary

My DictionaryLoaderClass:

internal static class SharedDictionaryManager
{
    internal static ResourceDictionary SharedDictionary
    {
        get
        {
            if (_sharedDictionary == null)
            {
                var resourceLocater =
                    new Uri(@"/pack://application:,,,/WPF_Controls;component/Styles/Globals.xaml", UriKind.Relative);
                _sharedDictionary =
                    (ResourceDictionary)Application.LoadComponent(resourceLocater);
            }
            return _sharedDictionary;
        }
    }


    private static ResourceDictionary _sharedDictionary;
}

and in every user control's constructor:

public SearchPanel()
{
    InitializeComponent();
    Resources.MergedDictionaries.Add(SharedDictionaryManager.SharedDictionary);
}

But I always get an exception at runtime that the key "DefaultSearchImage" can't be found...

Upvotes: 0

Views: 3362

Answers (1)

Joe
Joe

Reputation: 7004

If you want it to be loaded for every user control as a global style, why not just load it into the window resources? Anything added to the tree will then inherit the applicable styles:

<Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="600" Width="800">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Styles/Globals.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
...content including UserControls
</Window>

You can then access it as a static resource:

Property="{StaticResource ResourceKey=DefaultSearchImage}"

and in the code-behind:

(String)Resources["DefaultSearchImage"];

or non UI code:

(String)Application.Current.Resources["DefaultSearchImage"];

Though I'd suggest something like this:

<system:String x:Key="DefaultSearchImagePath">pack://application:,,,/WPF_Controls;component/Images/Search.png</system:String>
<BitmapImage x:Key="DefaultSearchImage" UriSource=DefaultSearchImage />

This will also allow re-uses of the user control to behave as anyone expects. If you, or another developer on the project want to change that image, they just need to put their own style up there without it being overridden run-time later on (who's going to think to look there?)

It's a great strength of WPF.

Upvotes: 2

Related Questions