3
votes

here is a demonstration of the problem :

from a simple window :

<Window x:Class="TestWpfStaticResource.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<TextBlock Text="{StaticResource TestString}">
    <TextBlock.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Resources.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </TextBlock.Resources>
</TextBlock>

I'm trying to access a resource in a ResourceDictionary :

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

Visual Studio 2010 shows my window with the expected result but when running the application I obtain this exception :

Cannot find resource named 'TestString'. Resource names are case sensitive.

Note 1 : when using a DynamicResource the result is fine in VS 2010 and at runtime.

Note 2 : putting the reference to the resource dictionary outside of the TextBlock, in the Windows Resources for instance, gives the expected result but my real scenario does not allow that.

So, what am I doing wrong and how to obtain the expected result ?

ANSWER : after more testing it appears that the XAML parser is quite minimal and parses content as it comes, sequentially, without trying to interpret anything. So declaration order is important : you have to put the reference to the "Text" property AFTER the reference to the dictionary. And the only way to do that seems to wrap the reference to the StaticResource in a "Binding" element.

Thanks in advance.

1

1 Answers

4
votes

I think the problem is that when it tries to find the static resource, it hasn't yet been merged into the current resource dictionary... not sure though.

Doing it like this seems to work:

    <TextBlock>
        <TextBlock.Resources>    
            <ResourceDictionary>
                 <ResourceDictionary.MergedDictionaries>
                       <ResourceDictionary Source="Resources.xaml"></ResourceDictionary>
                 </ResourceDictionary.MergedDictionaries>
            </ResourceDictionary>
       </TextBlock.Resources>

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