我的 WPF 样式设置器可以使用模板绑定吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1351635/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 20:56:06  来源:igfitidea点击:

Can my WPF Style Setter use a TemplateBinding?

wpfxamlstylestemplatebinding

提问by devuxer

I'm trying to do something like this...

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

<Style
    x:Key="MyBorderStyle"
    TargetType="Border">
    <Setter
        Property="BorderBrush"
        Value="{StaticResource MyBorderBrush}" />
    <Setter
        Property="Background"
        Value="{StaticResource MyBackgroundBrush}" />
    <Setter
        Property="Padding"
        Value="{TemplateBinding Padding}" />
</Style>

...but I get the error: 'Padding' member is not valid because it does not have a qualifying type name.

...但我收到错误: 'Padding' member is not valid because it does not have a qualifying type name.

How do I provide a "qualifying type name"?

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

Note: The reason I'm trying to do this, is that I'd like to include the same Border in a series of similar ControlTemplates.

注意:我尝试这样做的原因是我想在一系列类似的 ControlTemplate 中包含相同的 Border。

Thanks.

谢谢。

EDIT:

编辑:

Well I tried this...

嗯,我试过这个...

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

...and it actually compiled, but then when I ran the app, I got a XamlParseException:

...它实际上已编译,但是当我运行该应用程序时,我得到了一个XamlParseException

Cannot convert the value in attribute 'Value' to object of type ''.

Cannot convert the value in attribute 'Value' to object of type ''.

I thought maybe qualifying Paddingwith GridViewColumnHeader(which is the ControlTemplate I want to use this style with) would work, but no dice.

我想,也许有资格PaddingGridViewColumnHeader(这是我想用这种风格与控件模板)的工作,但没有骰子。

EDIT 2:

编辑2:

Well, according to the documentation for TemplateBinding, it says:

好吧,根据 的文档TemplateBinding,它说:

Links the value of a property in a control template to be the value of some other exposed property on the templated control.

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

So it sounds like what I'm trying to do is just plain impossible. I really would like to be able create reusable styles for certain controls in my control templates, but I guess the template bindings cannot be included in these styles.

所以听起来我想要做的事情简直是不可能的。我真的希望能够为我的控件模板中的某些控件创建可重用的样式,但我猜模板绑定不能包含在这些样式中。

回答by Shane Arney

This should work for the case where you're templating a control and you want to bind the value of a property of that control to a property of a different control inside the template. In your case you're templating something (call it MyControl), and that template will include a border whose Padding should be bound to MyControl's padding.

这应该适用于您对控件进行模板化并且希望将该控件的属性值绑定到模板内不同控件的属性的情况。在您的情况下,您正在模板化某些内容(称为 MyControl),并且该模板将包含一个边框,其 Padding 应绑定到 MyControl 的填充。

From MSDN documentation:

MSDN 文档

A TemplateBinding is an optimized form of a Binding for template scenarios, analogous to a Binding constructed with {Binding RelativeSource={RelativeSource TemplatedParent}}.

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

For whatever reason, specifying TemplatedParent as the source for the binding doesn't seem to work within Style Setters. To get around that you can specify the relative parent to be an AncestorType of the control you're templating (which effectively finds the TemplatedParent providing you haven't embedded other MyControls in the MyControl template).

无论出于何种原因,将 TemplatedParent 指定为绑定源似乎在样式设置器中不起作用。为了解决这个问题,您可以将相对父项指定为您正在模板化的控件的 AncestorType(如果您没有在 MyControl 模板中嵌入其他 MyControl,它可以有效地找到 TemplatedParent)。

I used this solution when I was trying to custom template a Button control in which the (String) Content of the Button needed to be bound to the Text property of a TextBlock in the ControlTemplate for the button. Here's what that code looked like:

当我尝试自定义模板按钮控件时,我使用了此解决方案,其中按钮的(字符串)内容需要绑定到按钮的 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>

回答by Kent Boogaart

A property can be qualified simply by prefixing it with the type name. For example, Border.Paddinginstead of Padding.

一个属性可以简单地通过在它前面加上类型名称来限定。例如,Border.Padding代替Padding.

However, I'm not sure it makes sense for your scenario. TemplateBindings are used inside a control template.

但是,我不确定这对您的场景是否有意义。TemplateBindings 在控件模板中使用。

回答by Avrohom

Yes Definitely,

当然是,

The {TemplateBinding ...}shortcut is not available in a Setter.

{TemplateBinding ...}快捷方式在 Setter 中不可用。

But nobody will stop you using the full verbose version.

但是没有人会阻止您使用完整的详细版本。

Such as: Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Padding}".

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