3

I am building a WPF app with several assemblies, and I want to share a resource dictionary among them. That requires a ComponentResourceKey. I have built a small demo to test out the CRK, and I can't seem to get it working.

My demo has two projects, a WPF project called Demo, and a DLL called Common. The Common project has a folder called Themes. It contains my resource dictionary, generic.xaml. Here is the text of the Resource dictionary:

<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Common" >

    <SolidColorBrush 
        x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type local:SharedResources}, ResourceId=RedSolidBrush}" 
        Color="Red"/>

</ResourceDictionary>

Common also contains a class called SharedResources.cs. It contains a property for referencing the Brush resource in the dictionary:

public static ComponentResourceKey RedSolidBrush
{
    get { return new ComponentResourceKey(typeof (SharedResources), "RedSolidBrush"); }
}

Finally, the main window in my Demo project references the brush resource to fill a rectangle:

<Window x:Class="ComponentResourceKeyDemo.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:res="clr-namespace:Common;assembly=Common"
    Title="Window1" Height="300" Width="300">
    <Grid>
        <Rectangle Height="100" Width="100" Stroke="Black" Fill="{DynamicResource {ComponentResourceKey TypeInTargetAssembly={x:Type res:SharedResources}, ResourceId=RedSolidBrush}}" />
    </Grid>
</Window>

I can't find the reason it's not working. It compiles fine in VS 2008 and Blend, but the resource isn't invoked. The only clue I have is an error message in Blend:

The Resource "{ComponentResourceKey ResourceId=RedSolidBrush, TypeInTargetAssembly={x:Type res:SharedResources}}" could not be resolved.

Any idea why this isn't working? Thanks for your help.

David Veeneman
  • 18,912
  • 32
  • 122
  • 187
  • I used the following example from "Pro WPF in C# 2008"in building my demo: http://books.google.com/books?id=XWu70Oqz6RIC&pg=PA344&lpg=PA344&dq=wpf+"sharing+resources+between+assemblies"&source=bl&ots=FMQU9g3whX&sig=rhK8YR-OUddEKmSBMqZXv45gxNc&hl=en&ei=JlqpSqf5NNKBtge6jqXYBw&sa=X&oi=book_result&ct=result&resnum=1#v=onepage&q=wpf%20%22sharing%20resources%20between%20assemblies%22&f=false – David Veeneman Sep 14 '09 at 16:14

1 Answers1

4

I found my problem. I was confusing the Component Resource Key with the Resource ID inside the resource dictionary. In other words, my Component Resource Key was the same as the Resource ID. I changed my static property to this:

public static ComponentResourceKey RedBrushKey
{
    get {return new ComponentResourceKey(typeof(SharedResources), "RedSolidBrush"); }
}

The property name is now RedBrushKey, instead of RedSolidBrush. And the key is now working.

David Veeneman
  • 18,912
  • 32
  • 122
  • 187
  • 1
    I also made one other change to my demo app. Originally, I had created a plain-vanilla Class Library project to hold the shared resource dictionary. I deleted that project and replaced it with a WPF Custom Control Library. I did some later testing, and it appears that the type of the project is important. A simple Class Library set up the same way as my WPF Custom Control Library wouldn't work. – David Veeneman Sep 14 '09 at 22:59
  • The solution also works with plain Class Library projects. The retrofit for a Class Library to support Component Resource Key markup extensions is described in this thread: http://stackoverflow.com/questions/2089041/differences-between-wpf-custom-control-library-and-plain-class-library/2094123#2094123 – David Veeneman Jan 19 '10 at 16:18
  • I discovered a simpler approach to cross-assembly resource sharing, using Pack URIs. It is explained here: http://stackoverflow.com/questions/2095031/wpf-sharing-resources-across-assemblies – David Veeneman Jan 19 '10 at 19:19
  • 1
    Are you sure the key and the ID being the same was the problem? I do the exact same thing and don't have issues like this. Though I use a readonly static to avoid new'ing it up every time: public static readonly ComponentResourceKey Foo = new ComponentResourceKey(typeof(Blah), "Foo"); – scobi Sep 17 '10 at 01:29