gpt4 book ai didi

WPF ControlTemplate 打破样式

转载 作者:行者123 更新时间:2023-12-04 01:40:04 25 4
gpt4 key购买 nike

有用的东西

我需要设置作为 StackPanel 子项的某种类型的控件的样式。我正在使用:

<StackPanel>
<StackPanel.Resources>
<Style TargetType="{x:Type TextBlock}">...</Style>
</StackPanel.Resources>
<TextBlock ...>
...
</StackPanel>

这很好用!每个 TextBlock 都会查看其父级(StackPanel)的资源,以找出它的样式。将 TextBlock 嵌套到 StackPanel 下多远都没有关系......如果它在其直接父级中没有找到样式,它将查看其父级的父级等等,直到找到某些东西(在这种情况下) ,在 ) 中定义的样式。

不起作用的东西

当我将 TextBlock 嵌套在具有模板的 ContentControl 中时遇到了问题(请参阅下面的代码)。 ControlTemplate 似乎破坏了 TextBlock 从其 parent 、祖 parent 、...

ControlTemplate 的使用似乎有效地消除了 TextBlock 寻找其正确样式(StackPanel.Resources 中的样式)的方法。当它遇到 ControlTemplate 时,它​​停止在树上的资源中寻找它的样式,而是默认为应用程序本身的 MergedDictionaries 中的样式。

<StackPanel Orientation="Vertical" Background="LightGray">
<StackPanel.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="Green" />
</Style>
</StackPanel.Resources>

<TextBlock Text="plain and simple in stackpanel, green" />
<ContentControl>
<TextBlock Text="inside ContentControl, still green" />
</ContentControl>
<ContentControl>
<ContentControl.Template>
<ControlTemplate TargetType="{x:Type ContentControl}">
<StackPanel Orientation="Vertical">
<ContentPresenter />
<TextBlock Text="how come this one - placed in the template - is not green?" />
</StackPanel>
</ControlTemplate>
</ContentControl.Template>
<TextBlock Text="inside ContentControl with a template, this one is green as well" />
</ContentControl>

</StackPanel>

除了将 StackPanel.Resources 中的 Style 复制到 ControlTemplate.Resources 之外,有没有办法让 ControlTemplate 中的 TextBlock 找到定义的样式?

谢谢...

最佳答案

WPF 考虑 ControlTemplates成为边界,并且不会在模板内部应用隐式样式(没有 x:Key 的样式)。

但是这个规则有一个异常(exception):任何继承自 Control 的东西。将应用隐式样式。

所以你可以使用 Label而不是 TextBlock ,它将应用在 XAML 层次结构中进一步定义的隐式样式,但是因为 TextBlock继承自 FrameworkElement而不是 Control ,它不会自动应用隐式样式,您必须手动添加它。

我最常见的解决方法是在 ControlTemplate.Resources 中添加一个隐式样式。即 BasedOn现有隐式TextBlock风格

    <ControlTemplate.Resources>
<Style TargetType="{x:Type TextBlock}"
BasedOn="{StaticResource {x:Type TextBlock}}" />
<ControlTemplate.Resources>

其他常见的解决方法是:
  • 将隐式样式放入 <Application.Resources> .放置在这里的样式将适用于您的整个应用程序,无论模板边界如何。不过要小心,因为它会将样式应用于 TextBlocks其他控件的内部,如按钮或组合框
    <Application.Resources>
    <Style TargetType="{x:Type TextBlock}">
    <Setter Property="Foreground" Value="Green" />
    </Style>
    </Application.Resources>
  • 使用 Label而不是 TextBlock因为它继承自 Control ,因此将应用在 ControlTemplate 之外定义的隐式样式
  • 给基本样式一个 x:Key并将其用作隐式 TextBlock 的基本样式ControlTemplate里面的样式.它与顶级解决方案几乎相同,但是它用于具有 x:Key 的基本样式。属性
    <Style x:Key="BaseTextBlockStyle" TargetType="{x:Type TextBlock}">
    <Setter Property="Foreground" Value="Green" />
    </Style>

    ...

    <ControlTemplate.Resources>
    <Style TargetType="{x:Type TextBlock}"
    BasedOn="{StaticResource BaseTextBlockStyle}" />
    <ControlTemplate.Resources>
  • 关于WPF ControlTemplate 打破样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14503146/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com