2
votes

Im trying to create a templated control that has a header, body, and footer content presenters.

So I created a class called BaseDockedSectionControl:

public class BaseDockedSectionControl:Control
{
    public BaseDockedSectionControl()
    {
        DefaultStyleKey = typeof(BaseDockedSectionControl);
    }

    public Grid Header
    {
        get { return (Grid)GetValue(HeaderProperty); }
        set { SetValue(HeaderProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Header.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty HeaderProperty =
        DependencyProperty.Register("Header", typeof(Grid), typeof(BaseDockedSectionControl), new PropertyMetadata(null));        

    public Grid Body
    {
        get { return (Grid)GetValue(BodyProperty); }
        set { SetValue(BodyProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Body.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty BodyProperty =
        DependencyProperty.Register("Body", typeof(Grid), typeof(BaseDockedSectionControl), new PropertyMetadata(null));



    public Grid Footer
    {
        get { return (Grid)GetValue(FooterProperty); }
        set { SetValue(FooterProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Footer.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty FooterProperty =
        DependencyProperty.Register("Footer", typeof(Grid), typeof(BaseDockedSectionControl), new PropertyMetadata(null));

          }

In App.XAML, I add a style to the Application.Resources:

<Style TargetType="local:BaseDockedSectionControl">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="local:BaseDockedSectionControl">
                        <Grid x:Name="RootElement">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="50"/>
                                <RowDefinition />
                                <RowDefinition Height="30"/>
                            </Grid.RowDefinitions>

                            <ContentPresenter Content="{TemplateBinding Header}"/>
                            <ContentPresenter Content="{TemplateBinding Body}"    Grid.Row="1"/>
                            <ContentPresenter Content="{TemplateBinding Footer}"  Grid.Row="2"/>                            
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

I then create a user control called Test.xaml, and enter the following xaml:

<UserControl x:Class="SilverlightIdeas.Test"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:SilverlightIdeas"
             xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">
        <local:BaseDockedSectionControl>            
            <local:BaseDockedSectionControl.Header>
                <TextBlock Text="This is the header" />
            </local:BaseDockedSectionControl.Header>
        </local:BaseDockedSectionControl>

    </Grid>
</UserControl>

When I type in the TextBlock, the intellisense doesnt recognize it, and when I type it in, I get the message "Property Header does not support values of type 'TextBlock'

What am I doing wrong?

2

2 Answers

1
votes

Two things fixed this.

  1. I made each of the dependency properties of type object

  2. Turns out that the problem was that the ContentPresenter seems to need to have an ending tag, rather than the self ending tag:

becomes

<ContentPresenter Content="{TemplateBinding Header}"></ContentPresenter>

Once I did that, things started working correctly

0
votes

You have defined your Header property in BaseDockedSectionControl to be of type Grid. TextBlock is not a Grid. Change the type of the Header property to Control instead.