我正在继承ItemsControl(我们称之为EnhancedItemsControl),我想公开ScrollViewerTemplate依赖项属性,这将允许用户为使用过的ScrollViewer选择性地指定自己的模板。我是这样做的:
public ControlTemplate ScrollViewerTemplate
{
get { return (ControlTemplate)GetValue(ScrollViewerTemplateProperty); }
set { SetValue(ScrollViewerTemplateProperty, value); }
}
public static readonly DependencyProperty ScrollViewerTemplateProperty =
DependencyProperty.Register(
"ScrollViewerTemplate",
typeof(ControlTemplate),
typeof(EnhancedItemsControl),
new UIPropertyMetadata(new ScrollViewer().GetValue(ScrollViewer.TemplateProperty))); //This doesn't work for me
在我的EnhancedItemsControl的默认样式中,然后我像这样包含ScrollViewer:
<ScrollViewer
Template="{TemplateBinding ScrollViewerTemplate}"
...
>
<ItemsPresenter
...
/>
</ScrollViewer>
当用户指定ScrollViewerTemplate时,此方法有效,但当他将其保留为默认值时,不会显示ScrollViewer(可能是因为它的模板为空)。如何告诉WPF 仅在非空时使用模板,否则使用默认模板? (它发生在我身上,我可以使用触发器仅在它不为空时设置模板,但我不喜欢在每个控件中为每个自定义属性设置触发器的想法......)
样式存在类似问题 - 如果我想让用户指定ScrollViewer样式,但用户没有指定它,则ScrollViewerStyle的值将为null(等于<ScrollViewer Style="{x:Null}" />
),这将停止正在应用的默认样式!
如何解决这个问题?谢谢!
答案 0 :(得分:1)
您可以使用Binding与TemplatedParent的RelativeSource代替使用TemplateBinding。这样您就可以在Binding中使用转换器。现在为Binding声明一个Converter(IValueConverter),并在ScrollViewerTemplate属性为null时返回默认模板。
答案 1 :(得分:1)
除了一点点之外你正在做的一切正确,你在UIPropertyMetadata
中指定的默认值实际上是空的,因为默认情况下它在新的ScrollViewer
中也是空的。
不要定义ScrollViewerTemplate
属性,而是定义ScrollViewerStyle
属性:
public Style ScrollViewerStyle
{
get { return (Style)GetValue(ScrollViewerTemplateProperty); }
set { SetValue(ScrollViewerTemplateProperty, value); }
}
public static readonly DependencyProperty ScrollViewerTemplateProperty =
DependencyProperty.Register(
"ScrollViewerStyle",
typeof(Style),
typeof(EnhancedItemsControl),
new UIPropertyMetadata(null));
在控件的默认样式中,为样式指定默认值:
<Setter Property="ScrollViewerStyle" Value="{StaticResource {x:Type ScrollViewer}}"/>
这实际上默认为当前主题定义的ScrollViewer样式。