WPF - 样式化无形控件:如何从第二级ControlTemplates访问控件的依赖属性?

时间:2009-10-15 16:41:09

标签: wpf dependency-properties controltemplate itemscontrol templatebinding

我正在扩展ItemsControlclass EnhancedItemsControl : ItemsControl),因为我想为它添加几个依赖属性 - 比如AlternativeContent,当集合中没有项目时会显示它们(想想'在itemscontrol中输入搜索条件并点击搜索'标签以获取搜索结果。)

我已将ItemsControl子类化,并添加了AlternativeContent dep。类型为FrameworkElement的属性。现在我想在Themes / Generic.xaml中提供默认样式(我已将ThemeInfoAttribute添加到AsseblyInfo,并在静态结构中提供元数据,如此excellent tutorial中所述。

该样式包含ControlTemplate,我需要在ItemsControl模板中使用第二个ControlTemplate,我在其中添加应显示ContentPresenter的{​​{1}}。

现在,我的问题是如何告诉AlternativeContent它应该从顶级ContentPresenter获取其内容?如果我在样式EnhancedItemsControl内,我会使用:

ControlTemplate

但是当我在 Content="{Binding AlternativeContent, RelativeSource={RelativeSource TemplatedParent}}" 的{​​{1}}里面的样式ItemsControl时,这显然不起作用,我需要引用不是父模板,而是引用祖父模板但是,ControlTemplate没有ControlTemplate参数。

我也尝试过:

TemplateBinding

但这也导致空AncestorLevel。我无法命名 Content="{Binding AlternativeContent, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type WPFControls:EnhancedItemsControl}}}" (因为它在ContentPresenter之外),所以我无法通过名称来引用它。我无法使用TemplatedParent ControlTemplate,因为这不会达到两级控制模板。 TemplatedParent RelativeBinding奇怪地无效。

知道如何解决这个问题吗?谢谢!

Generic.xaml(摘录):

RelativeSource

控制代码:

FindAncestor

用法( <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>

1 个答案:

答案 0 :(得分:1)

哎呀,我的坏,

Content="{Binding AlternativeContent, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type WPFControls:EnhancedItemsControl}}}" 

实际上有效(但我的标记比示例中的标记更复杂,并且由于其他错误而未显示内容...)