views:

269

answers:

2

I am planning on writing a hierarchical organizational control, similar to an org chart. Several org chart implementations are out there, but not quite fit what I have in mind.

Binding fields in a DataTemplate to a custom object does not seem to work.

I started with a generic, custom control, i.e.

public class NodeBodyBlock : ContentControl
{
    public NodeBodyBlock()
    {
        this.DefaultStyleKey = typeof(NodeBodyBlock);
    }
}

It has a simple style in generic.xaml:

   <Style TargetType="org:NodeBodyBlock">
    <Setter Property="Width" Value="200" />
    <Setter Property="Height" Value="100" />
    <Setter Property="Background" Value="Lavender" />
    <Setter Property="FontSize" Value="11" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="org:NodeBodyBlock">
                <Border Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" 
                        Background="{TemplateBinding Background}" CornerRadius="4" BorderBrush="Black" BorderThickness="1" >
                    <Grid>
                        <VisualStateManager/> ... clipped for brevity
                        </VisualStateManager.VisualStateGroups>
                        <ContentPresenter Content="{TemplateBinding Content}"
                            HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

My plan now is to be able to use this common definition as a base definition of sorts, with customized version of it used to display different types of content.

A simple example would be to use this on a user control with the following style:

<Style TargetType="org:NodeBodyBlock" x:Key="TOCNode2">
        <Setter Property="ContentTemplate">
            <Setter.Value>
                <DataTemplate>
                    <StackPanel>
                        <TextBlock Text="{Binding Path=NodeTitle}"/>
                    </StackPanel>
                </DataTemplate>
            </Setter.Value>
        </Setter>
    </Style>

and an instance defined as

<org:NodeBodyBlock Style="{StaticResource TOCNode2}" x:Name="stTest" 
                       DataContext="{StaticResource DummyData}"  />

The DummyData is defined as

<toc:Node NodeNumber="mynum" NodeStatus="A" 
   NodeTitle="INLine Node Title!"    
   x:Key="DummyData"/>

With a simple C# class behind it, where each of the fields is a public property.

When running the app, the Dummy Data values simply do not show up in the GUI. A trivial test such as

<TextBlock Text="{Binding NodeTitle}" DataContext="{StaticResource DummyData}"/>

works just fine.

Any ideas around where I am missing the plot?

Update: Binding to the datacontext in the definition in generic.xaml works fine, but any binding in the ContentPresenter is lost.

A: 

Your control template is missing a binding on the ContentPresenter, it should look like this:-

                    <ContentPresenter Content="{TemplateBinding Content}"
                        ContentTemplate="{TemplateBinding ContentTemplate}"
                        HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
AnthonyWJones
I updated the ContentPresenter definition as you suggested, but no difference (yet). Thanks for the suggestion though!
Ryan Bates
A: 

I just ended up using this example as a base:

http://10rem.net/blog/2010/02/05/creating-customized-usercontrols-deriving-from-contentcontrol-in-wpf-4

Not quite sure what I missed, but the example works.

Ryan Bates