views:

983

answers:

3

I'm building a Silverlight control and I'm trying to set up bindings for the Header and Body ContentControls through their respective DataTemplates. I'm not sure why, but this does not work (silently fails). My only guess is that it is because the DataTemplates are StaticResources. Can anyone offer advice? The control has the following default template:

<Style TargetType="local:LayoutItem">
<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="local:LayoutItem">
            <StackPanel>
                <StackPanel.Resources>

                    <DataTemplate x:Key="DefaultHeaderTemplate">
                        <StackPanel>
                           <TextBlock Text="{Binding HeaderText}" FontSize="15"/>
                        </StackPanel>
                    </DataTemplate>

                    <DataTemplate x:Key="DefaultBodyTemplate">
                        <StackPanel>
                            <TextBlock Text="{Binding BodyText}" FontSize="12"/>
                        </StackPanel>
                    </DataTemplate>

                </StackPanel.Resources>

                <ContentControl x:Name="Header" 
                   ContentTemplate="{StaticResource DefaultHeaderTemplate}" />
                <ContentControl x:Name="Body" 
                   ContentTemplate="{StaticResource DefaultBodyTemplate}" />
            </StackPanel>
        </ControlTemplate>
   </Setter.Value>

Thanks!


Update

Actually, the following code does not work either, so my assumption about the StaticResources might be wrong.

<ContentControl x:Name="Header">
<ContentControl.ContentTemplate>
    <DataTemplate x:Key="DefaultHeaderTemplate">
        <StackPanel>
            <TextBlock Text="{Binding HeaderText}" FontSize="15"  />
        </StackPanel>
    </DataTemplate>
</ContentControl.ContentTemplate>
</ContentControl>
+1  A: 

You need to set the data context of the page somewhere. can be done in the code behind

/// ctor
public MyClass()
{
   this.DataContext = ObjectThatIsDataContext;
}

or in XAML:

<UserControl ...>
    <UserControl.Resources>
       <myNS:MyClass x:Name="TheContext" x:Key="TheContext" />    </UserControl.Resources>
    <Grid x:Name="LayoutRoot" Background="White" DataContext="{StaticResource TheContext}" >
        <TextBlock Text="{Binding Path=Field1}" />
    </Grid>
</UserControl>

See also this post

HTH, Mark

Mark Cooper
As mentioned in the above comments, I am already setting the DataContext.
Page Brooks
+1  A: 

This works on mine (3 Beta):

        <ContentControl x:Name="Header">
            <ContentControl.ContentTemplate>
                <DataTemplate >
                    <StackPanel>
                        <TextBlock Text="{Binding HeaderText}" FontSize="15"  />
                    </StackPanel>
                </DataTemplate>
            </ContentControl.ContentTemplate>
            <ContentPresenter />
        </ContentControl>

However, I don't know why it works...I thought it was because you could put your template round the presenter, but then played a bit more and realised that anything you wrap the contentpresenter in just gets completely ignored.

mattmanser
+1  A: 

I hate to answer my own question, but I got it working. It was really due to a problem elsewhere. For future reference, the following code works for me:

<Style TargetType="local:LayoutItem">
<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="local:LayoutItem">
            <StackPanel x:Name="LayoutRoot">
                <StackPanel.Resources>

                    <DataTemplate x:Key="DefaultHeaderTemplate">
                        <StackPanel>
                            <TextBlock FontSize="50" Text="{Binding Path=HeaderText}" />
                        </StackPanel>
                    </DataTemplate>

                </StackPanel.Resources>

                <ContentControl x:Name="Header" Content="{Binding}" ContentTemplate="{StaticResource DefaultHeaderTemplate}" />

            </StackPanel>
        </ControlTemplate>
    </Setter.Value>
</Setter>

Please note the Content="{Binding}" addition. This was important. :)

Page Brooks