开发者

Silverlight 4 - use StaticResource from one ResourceDictionary in another

开发者 https://www.devze.com 2023-02-27 19:02 出处:网络
If I have these dictionaries: dict1.xaml: <Color x:Key=\"Color1\">Red</Color> dict2.xaml: <SolidColorBrush x:Key=\"Brush1\" Color={StaticResource Color1} />

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>
   开发者_StackOverflow <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:

  • One for colors
  • One for implicit styles
  • Many for explicit styles

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!


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>


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.


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


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

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号