How to use template binding inside data template in custom control (Silverlight)
Asked Answered
I

2

15

I am trying to create control which will take ItemsSource and InnerTemplate and will show all the items wrapped in CheckBoxes.

The control has 2 dependency properties:

public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(CheckBoxWrapperList), null);
public static readonly DependencyProperty InnerTemplateProperty = DependencyProperty.Register("InnerTemplate", typeof(DataTemplate), typeof(CheckBoxWrapperList), null);

and here is the template:

<ControlTemplate TargetType="local:CheckBoxWrapperList">
    <Grid>
        <Grid.Resources>
            <DataTemplate x:Key="wrapper">
                <CheckBox>
                    <ContentPresenter ContentTemplate="{TemplateBinding InnerTemplate}" Content="{Binding}" />
                </CheckBox>
            </DataTemplate>
        </Grid.Resources>
        <ItemsControl ItemTemplate="{StaticResource wrapper}" ItemsSource="{TemplateBinding ItemsSource}" />
    </Grid>
</ControlTemplate>

However, this approach does not work.
Binding in the ControlPresenter.ContentTemplate using TemplateBinding does not work.
However, when I don't use template binding and reference the template as static resource, then it works as expected.

  • Why cannot I use the template binding inside the content presenter in datatemplate?
  • What am I missing here? Any special markup required?
  • Is there a way to achieve the expected behavior?

Thanks in advance.

Immediately answered 8/1, 2011 at 17:40 Comment(1)
Have you figured out this? I have the same problem.Amplification
A
14

TemplateBinding can only be used within a ControlTemplate, you're using it within a DataTemplate. (The fact that the DataTemplate is within a ControlTemplate doesn't matter)

Acey answered 19/7, 2011 at 16:5 Comment(0)
S
23

Silverlight and WPF

You can get around this with a relative source binding:

Instead of:

{TemplateBinding InnerTemplate}

You would use:

{Binding RelativeSource={RelativeSource AncestorType=local:CheckBoxWrapperList}, Path=InnerTemplate}

It's a bit messier but it works.

WinRT

WinRT doesn't have AncestorType. I've got something that works but it's kind of horrifying.

You can use an attached property to store a TemplateBinding value and then access it using ElementName...

<ControlTemplate TargetType="local:CheckBoxWrapperList">
    <Grid x:Name="TemplateGrid" magic:Magic.MagicAttachedProperty="{TemplateBinding InnerTemplate}">
        <Grid.Resources>
            <DataTemplate x:Key="wrapper">
                <CheckBox>
                    <ContentPresenter ContentTemplate="{Binding ElementName=TemplateGrid, Path=(magic:Magic.MagicAttachedProperty)}" Content="{Binding}" />
                </CheckBox>
            </DataTemplate>
        </Grid.Resources>
        <ItemsControl ItemTemplate="{StaticResource wrapper}" ItemsSource="{TemplateBinding ItemsSource}" />
    </Grid>
</ControlTemplate>

I don't know if there's a better way for WinRT.

Spiry answered 20/3, 2012 at 2:8 Comment(1)
@P.W. Urgh that's messy. Um. I've worked out something that technically works, adding to answer.Spiry
A
14

TemplateBinding can only be used within a ControlTemplate, you're using it within a DataTemplate. (The fact that the DataTemplate is within a ControlTemplate doesn't matter)

Acey answered 19/7, 2011 at 16:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.