Kir
Kir

Reputation: 3052

Silverlight 4 - use StaticResource from one ResourceDictionary in another

If I have these dictionaries:

dict1.xaml: <Color x:Key="Color1">Red</Color>

dict2.xaml: <SolidColorBrush x:Key="Brush1" Color={StaticResource Color1} />

This works:

App.xaml:

<MergedDictionaries>
  <ResourceDictionary Source="dict1.xaml"/>
<MergedDictionaries>

SomePage.xaml:

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

This does not:

App.xaml merging both at application level.

I get an error about Color1 not being found.

Why is this ? / Is there a way around it? I know this example is simplistic, but a real one would be too long. Basically I'm just trying to organize my styles and templates in different files:

edit: curiously, if I do this in code on Application_Startup, before setting the RootVisual property, I don't get the error... I'm just perplexed as to why!

Upvotes: 7

Views: 8062

Answers (4)

Ben
Ben

Reputation: 1

I'm with tam on this one. "The resource lookup logic in the collection of merged resource dictionaries is last in, first out." In other words, if you have multiple dictionaries where one references the other then the dictionary that contains the referenced resources has to be at the top of the stack. Make sure you are referencing them in the right order and be careful to make sure the dictionaries at the top of the stack have NO dependencies on the dictionaries at the bottom of the stack

<Application.Resources>         
 <ResourceDictionary>
  <ResourceDictionary.MergedDictionaries>                                     
   <ResourceDictionary Source="Dict1.xaml" /> 
   <ResourceDictionary Source="dependsOnDict1.xaml" />                   
  </ResourceDictionary.MergedDictionaries>         
 </ResourceDictionary>     
</Application.Resources> 

Upvotes: 0

zihotki
zihotki

Reputation: 5191

You can do it in a way proposed by @Anthony but there is one caveat here - if you use your 1st resource dictionary in, for example, 5 other dictionaries then it will be loaded 5 times and you'll have 6 copies of the same resource dictionary (it's in case when you referenced it in App.xaml) which is not very good for performance. This can be fixed using small subclass of silverlight's resource dictionary from here - http://softnotes.wordpress.com/2011/04/05/shared-resourcedictionary-for-silverlight/ .

Upvotes: 1

AnthonyWJones
AnthonyWJones

Reputation: 189457

Unfortunately you've run into an annoying limitation in the Silverlight resources system which I can only imagine is some optimization issue. There seems to be some asynchronous behaviour here where each dictionary in MergedDictionaries are loaded in parallel, hence when "dict2.xaml" is loading you cannot rely on content of "dict1.xaml" being present.

The simplest solution is to include the merging of Dict1 in Dict2:-

App.xaml:

<ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="dict2.xaml" />
<ResourceDictionary.MergedDictionaries>

Dict2.xaml:

<ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="dict1.xaml" />
    </ResourceDictionary.MergedDictionaries>
    .... <!-- dict2 resource -->
</ResourceDictionary>

Upvotes: 5

tam
tam

Reputation: 1583

This would be in App.xaml

<Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="dict1.xaml" />
                <ResourceDictionary Source="dict2.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>

as long as you are defining the dictionary before the other one I am a little suprised something similar to the above wouldn't work.

Upvotes: 1

Related Questions