我的WPF样式Setter能使用TemplateBinding吗?

26

我正在尝试做这样的事情...

<Style
    x:Key="MyBorderStyle"
    TargetType="Border">
    <Setter
        Property="Padding"
        Value="{TemplateBinding Padding}" />
</Style>

...但我得到了以下错误:

'Padding'成员无效,因为它没有合格的类型名称。

如何提供“合格的类型名称”?

注意:我尝试这样做的原因是,我想在一系列相似的ControlTemplates中包含相同的边框。

我也尝试了这个方案:

<Setter
    Property="Padding"
    Value="{TemplateBinding GridViewColumnHeader.Padding}" />

我尝试编译了代码,它成功通过了,但在运行应用程序时,出现了XamlParseException

无法将'Value'属性中的值转换为类型为''的对象。

我以为将 Padding 与我要使用此样式的 GridViewColumnHeader (这是 ControlTemplate) 合格化可能会有用,但没有效果。

编辑:

根据 TemplateBinding 的文档所说:

将控件模板中的属性值链接到模板控件上其他公开属性的值。

听起来我想做的事情根本就不可能。我真的很想能够为我的控件模板中的某些控件创建可重复使用的样式,但我猜测模板绑定不能包含在这些样式中。

3个回答

42
TemplateBinding 可以在控件模板中实现绑定,将模板内不同控件的属性进行绑定。在这个例子中,您正在对某个东西(称其为 MyControl)进行模板化,并且该模板将包括一个边框(Border),其 Padding 属性应该与 MyControl 的 Padding 属性进行绑定。

来自 MSDN 文档

TemplateBinding 是针对模板场景的一种优化形式的 Binding,类似于使用 {Binding RelativeSource={RelativeSource TemplatedParent}} 构造的 Binding。

但是由于某种原因,在样式设置器(Style Setters)中指定 TemplatedParent 作为绑定源似乎不起作用。为了解决这个问题,您可以指定相对父级(AncestorType)为您正在进行模板化的控件的类型(这有效地找到了 TemplatedParent,前提是您没有在 MyControl 模板中嵌入其他 MyControls)。

当我尝试在自定义模板化 Button 控件时对 (String) Content 进行绑定,使其绑定到按钮的 ControlTemplate 中 TextBlock 的 Text 属性时,我使用了这个解决方案。下面是这段代码的样子:

<StackPanel>
    <StackPanel.Resources>
        <ControlTemplate x:Key="BarButton" TargetType="{x:Type Button}">
            <ControlTemplate.Resources>
                <Style TargetType="TextBlock" x:Key="ButtonLabel">
                    <Setter Property="Text" Value="{Binding Path=Content, RelativeSource={RelativeSource AncestorType={x:Type Button}} }" />
                </Style>
            </ControlTemplate.Resources>
            <Grid>
                <!-- Other controls here -->
                <TextBlock Name="LabelText" Style="{StaticResource ButtonLabel}" />
            </Grid>
        </ControlTemplate>
    </StackPanel.Resources>
    <Button Width="100" Content="Label Text Here" Template="{StaticResource BarButton}" />
</StackPanel>

6

{TemplateBinding ...}的缩写在Setter中不可用。

但是您仍然可以使用完整冗长版本,例如:

Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Padding}"


3

可以通过在属性名称前加上类型名称来限定属性。例如,Border.Padding 而不是 Padding

然而,我不确定它是否适用于您的情况。 TemplateBinding 用于控件模板内部。


1
谢谢,@Kent。你的回答给了我一个尝试的想法(请看我的编辑),但是它没有起作用。TemplateBinding只能在ControlTemplate内使用,这是有道理的……如果我能说服解析器我只想在ControlTemplate内使用这个样式就好了…… - devuxer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接