Как использовать привязку шаблона внутри шаблона данных в пользовательском элементе управления (Silverlight)

Я пытаюсь создать элемент управления, который примет ItemsSource и InnerTemplate и покажет все элементы, завернутые в CheckBox es.

Элемент управления имеет 2 свойства зависимостей:

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);

и вот шаблон:

<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>

Однако этот подход не работает.
Связывание в ControlPresenter.ContentTemplate с помощью TemplateBinding не работает.
Однако, когда я не использую привязку шаблона и не ссылаюсь на шаблон как на статический ресурс, он работает так, как ожидалось.

  • Почему я не могу использовать привязку шаблона внутри презентатора контента в datatemplate?
  • Что мне здесь не хватает? Требуется ли какая-либо специальная разметка?
  • Есть ли способ достичь ожидаемого поведения?

Спасибо заранее.

Ответ 1

TemplateBinding может использоваться только в ControlTemplate, вы используете его в DataTemplate. (Тот факт, что DataTemplate находится в ControlTemplate, не имеет значения)

Ответ 2

Silverlight и WPF

Вы можете обойти это с относительной привязкой источника:

Вместо:

{TemplateBinding InnerTemplate}

Вы бы использовали:

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

Это немного грязнее, но он работает.

WinRT

У WinRT нет AncestorType. У меня есть что-то, что работает, но это ужасно.

Вы можете использовать прикрепленное свойство, чтобы сохранить значение TemplateBinding, а затем получить к нему доступ с помощью 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>

Я не знаю, есть ли лучший способ для WinRT.