views:

1799

answers:

1

I'd like to programatically access static resources much as I would in XAML:

<TextBlock Text="{Binding Source={StaticResource My.Text.Key}}" />

This works whether my static resource is defined on the TextBlock, some parent element (e.g. UserControl) or even the application. It seems that either the StaticResource binding expression knows how to walk up the element tree, or the element itself does. I'd like to do the same thing programatically:

<UserControl x:Class="MyCustomControl" ...>
 <UserControl.Resources>
  <ResourceDictionary>
   <ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="Resources.xaml"/> <!-- Sets 'My.Text.Key' to System.String 'Hello, World!' -->
   </ResourceDictionary.MergedDictionaries>
  </ResourceDictionary>
 </UserControl.Resources>
</UserControl>

public partial class MyCustomControl
{
 public MyCustomControl()
 {
  InitializeComponent();
  string myCustomValue = this.Resources[MyCustomValue] as string; // myCustomValue becomes null!
 }
}

Even in this simple test, my resource can't seem to be accessed programatically. And this is the simplified version of what I was trying to really do: find a static resource via an element that I have a custom dynamic property attached to (e.g. uiElement.Resources[key]).

+5  A: 

Despite your comment to the contrary I doubt the use of "." in your resource key is really the source of your problem. In this situation the "." has no special meaning and would not impact how the resource is accessed. (I've tried and failed to reproduce any problem with it).

There is though a very big difference between using the {StaticResource MyName} mark up extension and an attempt to find the resource programmatically.

The markup extension causes the XamlParser to look for the specified key the Resources property of the FrameworkElement to which the property being assigned belongs. If the key is not found it looks for it in the parent FrameworkElement and it keeps going until it reaches the root FrameworkElement. If it is still not found it has a look in the Application's Resources property.

On the other hand this code:-

string myCustomValue = this.Resources[MyCustomValue] as string;

sf just looking in the single Resources property for the user control. No attempt is made to hunt down the key in ancestors or in the application resources. Its a simple Dictionary lookup. This I suspect is what was really tripping you up.

Having said that I would say the using "." in a resource key may not be a good idea. The "." does have meaning in various XAML scenarios already so using it in key names as well has the potential to confuse a developer reading the code even though Silverlight is quite happy with it.

AnthonyWJones
Your answer is the direct answer I was looking for: XAML-parse-time resource look is hierarchial while progrmatic resource access is not. I do wish that the hierarchial logic that the XAML parser uses was exposed for programatic use as well, though.I'm not convinced the dots were an issue, either. And the dots DO cause a problem for ReSharper: it confuses its syntax highlighting.My intention is using dots was to better separate the resources into pseudo-namespaces so that each of my Prism modules can define resources and not run into collisions with other modules.
Trinition