【发布时间】:2009-10-15 16:41:09
【问题描述】:
我正在扩展ItemsControl (class EnhancedItemsControl : ItemsControl),因为我想向它添加几个依赖属性——比如AlternativeContent,它将在集合中没有项目时显示(想想'输入搜索词并在项目控件中点击搜索标签以获取搜索结果)。
我将ItemsControl 子类化并添加了AlternativeContent 部门。 FrameworkElement 类型的属性。现在我想在 Themes/Generic.xaml 中提供默认样式(我已将 ThemeInfoAttribute 添加到 AsseblyInfo,并在静态 costructor 中提供了元数据,如 excellent tutorial 中所述)。
样式包含一个ControlTemplate,我需要在ItemsControl 模板中使用第二个ControlTemplate,我在其中添加一个ContentPresenter,它应该显示AlternativeContent。
现在,我的问题是如何告诉ContentPresenter 它应该从顶级EnhancedItemsControl 获取其内容?如果我在风格的ControlTemplate 内,我会使用:
Content="{Binding AlternativeContent, RelativeSource={RelativeSource TemplatedParent}}"
但由于我在ItemsControl 的ControlTemplate 内部样式的ControlTemplate 中,这显然不起作用,我需要参考的不是父模板,而是祖父模板,但是,TemplateBinding没有AncestorLevel 参数。
我也试过了:
Content="{Binding AlternativeContent, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type WPFControls:EnhancedItemsControl}}}"
但这也会导致空的ContentPresenter。我不能命名TemplatedParent(因为它在ControlTemplate 之外),所以我不能通过名称来引用它。我不能使用TemplatedParentRelativeBinding,因为这不会超过两个级别的控制模板。而RelativeSource FindAncestor 奇怪地不起作用。
知道如何解决这个问题吗?谢谢!
Generic.xaml(摘录):
<Style TargetType="{x:Type WPFControls:EnhancedItemsControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type WPFControls:EnhancedItemsControl}">
<ItemsControl
x:Name="RootItemsControl"
ItemsSource="{Binding}"
ItemTemplate="{TemplateBinding ItemTemplate}"
Background="{TemplateBinding Background}"
HorizontalContentAlignment="Stretch"
>
<ItemsControl.Template>
<ControlTemplate>
<ScrollViewer
x:Name="ContentScrollViewer"
CanContentScroll="False"
>
<StackPanel
x:Name="InnerPanel"
>
<ItemsPresenter
Width="{Binding ActualWidth, ElementName=InnerPanel}"
MaxWidth="{Binding ActualWidth, ElementName=InnerPanel}"
HorizontalAlignment="Stretch"
/>
<ContentPresenter
Content="{Binding AlternativeContent, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type WPFControls:EnhancedItemsControl}}}"
>
<ContentPresenter.Style>
<Style>
<Setter Property="ContentPresenter.Visibility" Value="Collapsed" />
<Style.Triggers>
<DataTrigger
Binding="{Binding Items.Count, ElementName=RootItemsControl}"
Value="0">
<Setter Property="ContentPresenter.Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentPresenter.Style>
</ContentPresenter>
</StackPanel>
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
</ItemsControl>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
控制代码:
public class EnhancedItemsControl : ItemsControl
{
static EnhancedItemsControl()
{
DefaultStyleKeyProperty.OverrideMetadata(
typeof(EnhancedItemsControl),
new FrameworkPropertyMetadata(typeof(EnhancedItemsControl)));
}
public FrameworkElement AlternativeContent
{
get { return (FrameworkElement)GetValue(AlternativeContentProperty); }
set { SetValue(AlternativeContentProperty, value); }
}
// Using a DependencyProperty as the backing store for AlternativeContent. This enables animation, styling, binding, etc...
public static readonly DependencyProperty AlternativeContentProperty =
DependencyProperty.Register("AlternativeContent", typeof(FrameworkElement), typeof(EnhancedItemsControl), new UIPropertyMetadata(null));
}
用法(List<string> 提供为DataContext):
<WPFControls:EnhancedItemsControl Height="120" x:Name="EnhancedCollection"
>
<WPFControls:EnhancedItemsControl.AlternativeContent>
<WPFControls:CenteredLabel>
Alternative content
</WPFControls:CenteredLabel>
</WPFControls:EnhancedItemsControl.AlternativeContent>
<WPFControls:EnhancedItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" />
</DataTemplate>
</WPFControls:EnhancedItemsControl.ItemTemplate>
</WPFControls:EnhancedItemsControl>
【问题讨论】:
标签: wpf dependency-properties controltemplate itemscontrol templatebinding