WPF ControlTemplates 是否必须有 TargetType?

发布于 2024-09-17 13:15:16 字数 971 浏览 13 评论 0原文

WPF 中的 ControlTemplate 是否需要 TargetType?我正在重新设计一些控件,并注意到,comboboxitem、listiviewitem 和 listboxitem 都具有相同的模板:

    <ControlTemplate x:Key="ListBoxItemCT" TargetType="{x:Type ListBoxItem}">

    <Border x:Name="Bd" 
        SnapsToDevicePixels="true" 
        Background="{TemplateBinding Background}" 
        BorderBrush="{TemplateBinding BorderBrush}" 
        BorderThickness="{TemplateBinding BorderThickness}" 
        Padding="{TemplateBinding Padding}"
        CornerRadius="1">
        <ContentPresenter x:Name="cpItemContent"
            HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
            VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
            SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
            />
    </Border>

</ControlTemplate>

是否可以仅删除 TargetType 并为所有三个控件使用一个模板?我正在尝试这样做,但遇到了奇怪的错误和问题。我找不到 ControlTemplates 必须具有类型的任何具体参考。

Do ControlTemplates in WPF require a TargetType? I am restyling some controls, and notice that the comboboxitem, listiviewitem and listboxitem all have the same template:

    <ControlTemplate x:Key="ListBoxItemCT" TargetType="{x:Type ListBoxItem}">

    <Border x:Name="Bd" 
        SnapsToDevicePixels="true" 
        Background="{TemplateBinding Background}" 
        BorderBrush="{TemplateBinding BorderBrush}" 
        BorderThickness="{TemplateBinding BorderThickness}" 
        Padding="{TemplateBinding Padding}"
        CornerRadius="1">
        <ContentPresenter x:Name="cpItemContent"
            HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
            VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
            SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
            />
    </Border>

</ControlTemplate>

Is it possible to just remove the TargetType and have one template for all three? I'm trying to do this but get strange errors and problems. I can't find any specific reference that ControlTemplates must have a type.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

鲜血染红嫁衣 2024-09-24 13:16:56

文档 指出:

ControlTemplate 上的 TargetType 属性是必需的,如果
模板定义包含一个 ContentPresenter。

尽管它没有对此要求进行解释,但很可能是 John Bowen 的回答 给出的推理,您必须手动指定基本属性,例如 Content,否则这些属性将自动连接。

The documentation states this:

the TargetType property is required on a ControlTemplate if the
template definition contains a ContentPresenter.

Although it gives no explanation for this requirement, most likely it is the reasoning given by John Bowen's answer, that you will have to manually specify basic properties like Content that would otherwise be wired automatically.

花之痕靓丽 2024-09-24 13:16:41

它们都派生自 System.Windows.Controls.ContentControl,因此您可以将其作为目标。

They all derive from System.Windows.Controls.ContentControl, so you could target that instead.

甜妞爱困 2024-09-24 13:16:26

对 TargetType 没有要求,但如果您不指定 TargetType,其行为将与指定 Control 的 TargetType 相同。

  • 指定类型的主要优点是可以访问所有
    TemplateBindings 等类型的依赖属性
    和触发器,无需向所有者确认财产资格
    类型。

  • 如果没有 TargetType,您也可能会丢失隐式绑定,例如
    ContentPresenter 到 ContentControl.Content 属性。

一旦指定了 TargetType,该模板就只能应用于该类型的控件或从该类型派生的控件。要在不同类型之间共享,只需指定一个公共基类 - 在本例中为 ContentControl。

以下简单模板将给出相同的基本结果,但第一个更可取且更常见:

<ControlTemplate x:Key="CommonContentTemplate" TargetType="{x:Type ContentControl}">
    <Border x:Name="Bd" 
            SnapsToDevicePixels="true" 
            Background="{TemplateBinding Background}" 
            BorderBrush="{TemplateBinding BorderBrush}"
            BorderThickness="{TemplateBinding BorderThickness}" 
            Padding="{TemplateBinding Padding}"
            CornerRadius="1">
        <ContentPresenter x:Name="cpItemContent"
                          HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                          VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
                          SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
    </Border>
</ControlTemplate>

如果没有类型,则需要手动连接所有内容属性:

<ControlTemplate x:Key="CommonTemplate">
    <Border x:Name="Bd" 
            SnapsToDevicePixels="true" 
            Background="{TemplateBinding Background}" 
            BorderBrush="{TemplateBinding BorderBrush}"
            BorderThickness="{TemplateBinding BorderThickness}" 
            Padding="{TemplateBinding Padding}"
            CornerRadius="1">
        <ContentPresenter x:Name="cpItemContent"
                          HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                          VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
                          SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                          Content="{TemplateBinding ContentControl.Content}"
                          ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
                          ContentTemplateSelector="{TemplateBinding ContentControl.ContentTemplateSelector}"
                          ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}"/>
    </Border>
</ControlTemplate>

There isn't a requirement for a TargetType, but if you don't specify one it will behave the same as if you specify a TargetType of Control.

  • The main advantage that specifying a type gives you is access to all
    of that type's Dependency Properties in things like TemplateBindings
    and Triggers without having to qualify the property with the owner
    type.

  • Without a TargetType you can also lose implicit bindings, like
    ContentPresenter to the ContentControl.Content property.

Once you do specify a TargetType that template can only be applied to controls of that type or derived from that type. To share between different types just specify a common base class - ContentControl in this case.

The following simple templates will give the same basic result but the first is preferable and more common:

<ControlTemplate x:Key="CommonContentTemplate" TargetType="{x:Type ContentControl}">
    <Border x:Name="Bd" 
            SnapsToDevicePixels="true" 
            Background="{TemplateBinding Background}" 
            BorderBrush="{TemplateBinding BorderBrush}"
            BorderThickness="{TemplateBinding BorderThickness}" 
            Padding="{TemplateBinding Padding}"
            CornerRadius="1">
        <ContentPresenter x:Name="cpItemContent"
                          HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                          VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
                          SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
    </Border>
</ControlTemplate>

Without the type all of the Content properties need to be wired up manually:

<ControlTemplate x:Key="CommonTemplate">
    <Border x:Name="Bd" 
            SnapsToDevicePixels="true" 
            Background="{TemplateBinding Background}" 
            BorderBrush="{TemplateBinding BorderBrush}"
            BorderThickness="{TemplateBinding BorderThickness}" 
            Padding="{TemplateBinding Padding}"
            CornerRadius="1">
        <ContentPresenter x:Name="cpItemContent"
                          HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
                          VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
                          SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                          Content="{TemplateBinding ContentControl.Content}"
                          ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
                          ContentTemplateSelector="{TemplateBinding ContentControl.ContentTemplateSelector}"
                          ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}"/>
    </Border>
</ControlTemplate>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文