Dan*_*ens 11 wpf xaml nested controltemplate
有效的东西
我需要设置某种类型的控件的样式,这些控件是StackPanel的子代.我正在使用:
<StackPanel>
<StackPanel.Resources>
<Style TargetType="{x:Type TextBlock}">...</Style>
</StackPanel.Resources>
<TextBlock ...>
...
</StackPanel>
Run Code Online (Sandbox Code Playgroud)
这很好用!每个TextBlock都会查看它的父级(StackPanel)的资源,以了解它应该如何设置样式.将TextBlock嵌套到StackPanel上的距离无关紧要...如果它在其直接父级中找不到样式,它将查看其父级的父级,依此类推,直到找到某些东西(在这种情况下) ,中所定义的风格).
那些不起作用的东西
当我在ContentControl中嵌套TextBlock时遇到问题,ContentControl有一个模板(参见下面的代码).ControlTemplate似乎破坏了TextBlock从其父母,祖父母那里检索其风格的方式......
有效地使用ControlTemplate似乎可以解决TextBlock找到其合法风格的方法(StackPanel.Resources中的风格).遇到ControlTemplate时,它会停止在树上的资源中查找其样式,而是默认使用Application本身的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>
Run Code Online (Sandbox Code Playgroud)
有没有办法 - 除了将StackPanel.Resources中的Style复制到ControlTemplate.Resources之外 - 使ControlTemplate内的TextBlock找到定义的样式?
谢谢...
Rac*_*hel 22
WPF认为ControlTemplates是边界,并且不会x:Key在模板内部应用隐式样式(没有a的样式).
但是这个规则有一个例外:继承的任何东西Control都会应用隐式样式.
因此,您可以使用a Label而不是a TextBlock,它将应用在XAML层次结构中进一步定义的隐式样式,但是由于TextBlock继承FrameworkElement而不是Control,它将不会自动应用隐式样式,您必须手动添加它.
我最常见的解决方法ControlTemplate.Resources是BasedOn在现有的隐式样式中添加隐式TextBlock样式
<ControlTemplate.Resources>
<Style TargetType="{x:Type TextBlock}"
BasedOn="{StaticResource {x:Type TextBlock}}" />
<ControlTemplate.Resources>
Run Code Online (Sandbox Code Playgroud)
解决这个问题的其他常见方法是:
将隐式样式放入<Application.Resources>.无论模板边界如何,此处放置的样式都将适用于整个应用程序.但要小心,因为它会将样式应用于TextBlocks其他控件的内部,如Buttons或ComboBoxes
<Application.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="Green" />
</Style>
</Application.Resources>
Run Code Online (Sandbox Code Playgroud)使用a Label代替a,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>
Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
3805 次 |
| 最近记录: |