我用弹出窗口编写了一个用户控件,其内容正在控件之外设置。该控件的ControlTemplate如下所示:
<ControlTemplate TargetType="local:InfoIcon">
<Grid>
<ToggleButton x:Name="HelpButton" Style="{StaticResource HelpButton}" />
<Popup PlacementTarget="{Binding ElementName=HelpButton}" Placement="Bottom"
IsOpen="{Binding ElementName=HelpButton, Path=IsChecked, Mode=TwoWay}" StaysOpen="False">
<Border BorderBrush="#767676" BorderThickness="1"
Background="#f1f2f7">
<Border.Resources>
<!-- Important -->
<Style TargetType="Label">
<Setter Property="Foreground" Value="#575757" />
</Style>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="#575757" />
</Style>
<!-- /Important -->
</Border.Resources>
<ContentPresenter Content="{TemplateBinding HelpContent}" />
</Border>
</Popup>
</Grid>
</ControlTemplate>
Important
部分 - 我想为项目分配自定义样式,这些项目放在弹出窗口中(它可作为可点击的提示)
我正在以下列方式使用我的控件:
<local:MyControl>
<local:MyControl.HelpContent>
<TextBlock>Ala ma kota</TextBlock>
</local:MyControl.HelpContent>
</local:MyControl>
但是,尽管边框中有样式,TextBlock
的文本颜色始终从其父级继承值(使用Snoop检查) - 在白色背景上生成白色文本。
你可以降低small PoC application, which demonstrates the problem。
我的观察:
Label
。它仅适用于TextBlock
。TextBlock.Foreground="Red"
时,TextBlock
变为红色,仍然忽略样式(但现在使用边框中的颜色)。TextBlock
实际已 Style
已正确解析。但是尽管它是shouldn't,它使用继承的值而不是样式中指定的值。我该如何解决这个问题?为什么会这样?
答案 0 :(得分:6)
我在微软论坛上收到了回复;如果有人遇到同样的问题,我会留在这里。
不同之处在于TextBlock不是一个控件,即它没有任何ControlTemplate,因此当它位于StackPanel内部时,隐式样式不会应用于它。有关详细信息,请参阅以下页面:http://blogs.msdn.com/b/wpfsdk/archive/2009/08/27/implicit-styles-templates-controls-and-frameworkelements.aspx
您可以使用Label元素或明确设置TextBlock元素的样式。
- 马格努斯(MM8)
答案 1 :(得分:1)
<强> EDIT2 强>
我已将UserControl
的前景设置为其他内容。此行为是因为UserControl的子TextBlock
控件以某种方式继承Foreground-Settings。这与弹出窗口或我们尝试的其他方法无关。
我在这里遇到了类似问题的另一个问题:Cannot override controls foreground colour in wpf
我建议接受这种奇怪的行为,只需设置UserControl的Foreground
颜色:
<Style TargetType="{x:Type local:InfoIcon}">
<Setter Property="Foreground" Value="Red"/>
</Style>
之前的修改
你对这种奇怪的行为感到好奇,但在查看你的PoC之后,这是相当明显的:) Popup有一些附加的属性TextElement.*
,你可以在弹出窗口中设置文本元素的样式。这对我来说也是新的,之后我会再研究一下。不过:您的问题的解决方法是不要设置TextBlock
的样式,而是设置Popup
的样式。您的代码可能如下所示:
<ControlTemplate TargetType="{x:Type local:InfoIcon}">
<ControlTemplate.Resources>
<Style TargetType="Popup">
<Setter Property="TextElement.Foreground" Value="Red"/>
</Style>
<Style TargetType="Label">
<Setter Property="Foreground" Value="Red" />
</Style>
</ControlTemplate.Resources>
<Grid>
<ToggleButton x:Name="TB" Width="16" Height="16"/>
<Popup Placement="Bottom" PlacementTarget="{Binding ElementName=TB}" IsOpen="{Binding ElementName=TB, Path=IsChecked}" StaysOpen="False">
<ContentPresenter Content="{TemplateBinding InfoContent}"/>
</Popup>
</Grid>
</ControlTemplate>
我将样式更改为控件之外,当然您可以直接使用弹出窗口的附加属性。但最初你想知道它如何与边框附加的样式一起使用,现在添加样式的位置并不重要。例如,您可以使用ResourceDictionary。
答案 2 :(得分:0)
作为建议,不应该这样:
TargetType="local:InfoIcon"
是这样的吗?
TargetType="{x:Type local:InfoIcon}"
答案 3 :(得分:0)
也许你有一些TextBlock样式定义它应该采用父控件的前景。
您是否尝试添加这样的BasedOn属性?
<Style TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}">
<Setter Property="Foreground" Value="#575757" />
</Style>
答案 4 :(得分:0)
我尝试使用您的代码示例,这有效:
<ContentPresenter Content="{TemplateBinding InfoContent}">
<ContentPresenter.Style>
<Style TargetType="{x:Type ContentPresenter}">
<Setter Property="TextBlock.Foreground" Value="Red" />
</Style>
</ContentPresenter.Style>
<ContentPresenter.Resources>
<Style TargetType="{x:Type Label}">
<Setter Property="Foreground" Value="Red" />
</Style>
</ContentPresenter.Resources>
</ContentPresenter>
这有点奇怪,因为当我在ContentPresenter.Style中放置Label控件的Foreground setter时,这次它的Label不起作用......我认为这是因为Label被认为是ContentControl而TextBlock是只是一个FrameworkElement。
答案 5 :(得分:0)
有另一个问题引起的类似问题:
WPF中有一个奇怪的错误,它阻止将合并字典中定义的样式应用于第一个元素:
https://www.engineeringsolutions.de/wpf-fix-style-is-only-applied-to-first-element/