views:

146

answers:

0

I'm creating a silverlight 4 custom control. The control's template is defined through generic.xaml.

The control includes ItemsSource and ItemTemplate properties similar to an ItemsControl. The template includes (amongst other things) and ItemsControl which has its own DataTemplate, however inside that DataTemplate I have a ContentControl which I'd like to bind to my control's ItemTemplate property. Unfortunately this requires binding to a property on the TemplatedParent's TemplatedParent. How can this be done?

The simplified code below should help explain the issue. Essentially I need a binding expression for the ContentControl's ContentTemplate which binds to MyList.ItemTemplate.

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

    #region Properties
    public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(MyList), new PropertyMetadata(null));
    public IEnumerable ItemsSource
    {
        get { return (IEnumerable)GetValue(ItemsSourceProperty); }
        set { SetValue(ItemsSourceProperty, value); }
    }

    public static readonly DependencyProperty ItemTemplateProperty = DependencyProperty.Register("ItemTemplate", typeof(DataTemplate), typeof(MyList), new PropertyMetadata(null));
    public DataTemplate ItemTemplate
    {
        get { return (DataTemplate)GetValue(ItemTemplateProperty); }
        set { SetValue(ItemTemplateProperty, value); }
    }
    #endregion
}

<Style TargetType="local:MyList">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:MyList">
                <StackPanel>
                    <Button>ControlTOP</Button>
                    <ItemsControl ItemsSource="{TemplateBinding ItemsSource}">
                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <ContentControl Content="{Binding}" ContentTemplate="{TemplateBinding ItemTemplate}" />
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ItemsControl>
                    <Button>ControlBottom</Button>
                </StackPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

The only solution I've come up with so far is to have a 2nd hidden control which binds the ItemTemplate and then use a binding with ElementName to bind to that control, but this is rather ugly. e.g.

<ItemsControl x:Name="hiddenItems" Visibility="Collapsed"
    ItemTemplate="{TemplateBinding ItemTemplate}" />
<ItemsControl ItemsSource="{TemplateBinding ItemsSource}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <ContentControl 
                Content="{Binding}"
                ContentTemplate="{Binding ItemTemplate, ElementName=hiddenItems}"
                />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>