Как использовать привязку шаблона внутри шаблона данных в пользовательском элементе управления (Silverlight)
Я пытаюсь создать контроль, который примет ItemsSource
а также InnerTemplate
и покажет все предметы, завернутые в CheckBox
эс.
Элемент управления имеет 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
не работает.
Однако, когда я не использую привязку шаблона и ссылаюсь на шаблон как на статический ресурс, он работает как положено.
- Почему я не могу использовать привязку шаблона внутри предъявителя контента в шаблоне данных?
- Что мне здесь не хватает? Требуется ли специальная разметка?
- Есть ли способ добиться ожидаемого поведения?
Заранее спасибо.
2 ответа
TemplateBinding может использоваться только в ControlTemplate, вы используете его в DataTemplate. (Тот факт, что DataTemplate находится в ControlTemplate, не имеет значения)
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.