13

I'm learning WPF and started with this MSDN tutorial.

I was just following the tutorial. When I finished the code as per the tutorial and try to run I get an exception in a XAML page which says

'Provide value on 'System.Windows.StaticResourceExtension' threw an exception.' Line number '27' and line position '55'." . And inner exception reveals that error is "Cannot find resource named 'personItemTemplate'. Resource names are case sensitive.".

The culprit XAML is below.

<Page x:Class="ExpenseIt.ExpenseItHome"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" 
      d:DesignHeight="321" d:DesignWidth="532"
    Title="ExpenseIt - Home">

    <Grid Margin="10,0,10,10">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="230" />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="Auto" />
            <RowDefinition />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Label Grid.Column="1" Style="{StaticResource headerTextStyle}">View Expense Report</Label>
        <!-- Resource List Label-->
        <Border Grid.Column="1" Grid.Row="1" Style="{StaticResource listHeaderStyle}">
            <Label VerticalAlignment="Center" Foreground="White" FontWeight="Bold">Names</Label>
        </Border>
        <!-- Resource List-->
        <ListBox Name="peopleListBox" Grid.Column="1" Grid.Row="2" 
         ItemsSource="{Binding Source={StaticResource ExpenseDataSource}, XPath=Person}"
         ItemTemplate="{StaticResource personItemTemplate}">
        </ListBox>

        <!-- View button -->
        <Button Grid.Column="1" Grid.Row="3" Click="Button_Click" Style="{StaticResource buttonStyle}">View</Button>

        <!-- Set Background Image-->
        <Grid.Background>
            <ImageBrush ImageSource="watermark.png" />
        </Grid.Background>
        <Grid.Resources>

            <!-- Expense Report Data -->
            <XmlDataProvider x:Key="ExpenseDataSource" XPath="Expenses">
                <x:XData>
                    <Expenses xmlns="">
                        <Person Name="TommyVance" Department="Legal">
                            <Expense ExpenseType="Lunch" ExpenseAmount="50" />
                            <Expense ExpenseType="Transportation" ExpenseAmount="50" />
                        </Person>
                        <Person Name="PhilJackson" Department="Marketing">
                            <Expense ExpenseType="Document printing"
      ExpenseAmount="50"/>
                            <Expense ExpenseType="Gift" ExpenseAmount="125" />
                        </Person>
                        <Person Name="PaulBriggs" Department="Engineering">
                            <Expense ExpenseType="Magazine subscription" 
     ExpenseAmount="50"/>
                            <Expense ExpenseType="New machine" ExpenseAmount="600" />
                            <Expense ExpenseType="Software" ExpenseAmount="500" />
                        </Person>
                        <Person Name="AlfredNobel" Department="Finance">
                            <Expense ExpenseType="Dinner" ExpenseAmount="100" />
                        </Person>
                    </Expenses>
                </x:XData>
            </XmlDataProvider>
            <!-- Data Template to mention that Name should be fetched from the XMLDataProvider -->
            <!-- Name item template -->
            <DataTemplate x:Key="personItemTemplate">
                <Label Content="{Binding XPath=@Name}"/>
            </DataTemplate>
        </Grid.Resources>
    </Grid>
</Page>

I have the required template inside the Grid resources and so adding it as a static resource. Still, it throws the exception that the datatemplate is not available.

3 Answers 3

31

Move the <Grid.Resources> ... </Grid.Resources> to the top of your grid definition and it will work. The DataTemplate appears to need to be defined before it is referenced. I copied your sample into an app and confirmed that moving the Resources section up solved the problem.

Sign up to request clarification or add additional context in comments.

3 Comments

Yep, I tried that randomly just now and came here to update the answer. But you was first. :-) I'm accepting your answer. Any reason why the resource reference behaves like this?
Well, I don't know for sure. It would seem at a glance that it parses the XAML in sequential order, and so it doesn't know what 'personItemTemplate' is when it is first referenced. However, it does know what your 'ExpenseDataSource' is despite where it is placed. So... I will have to defer to someone with more expertise for a better explanation. :)
If you want a more dynamic experience, use DynamicResource. StaticResource resources are faster and prevent cyclical reference. It is not really this simple, but think of StaticResource as compile-time lookup, and DynamicResource as run-time reflection lookup. DynamicResource is "better", but you pay for the flexibility at run-time. Prefer StaticResource when it will work.
5

There are several reasons for this error. The solution to my proplem was that I failed to add a "InitializeComponent();" in the constructor of Application therefore the Xaml containing the ResourceDictionary was never initialized. Hence the error "Can not find..." I failed to mention that I am hand-coding. If you generating code via Visual Studio, this is not required.

Comments

5

I got the same error, but none of the answers above worked.

My error got solved by changing the XAML on the datatemplate from :

<DataTemplate DataType="local:DtoDmParent" x:Key="dataTemplateDtoDmParent"  >
    <TextBlock Text="test"/>
</DataTemplate>

to

<DataTemplate x:Key="dataTemplateDtoDmParent" DataType="local:DtoDmParent" >
    <TextBlock Text="test"/>
</DataTemplate>

Changing so the Datatype parameter was after the x:key parameter

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.