Wpf,样式未应用

时间:2013-12-12 07:33:22

标签: c# wpf xaml

我用弹出窗口编写了一个用户控件,其内容正在控件之外设置。该控件的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变为红色,仍然忽略样式(但现在使用边框中的颜色)。
  • Snoop通知,此TextBlock实际 Style已正确解析。但是尽管它是shouldn't,它使用继承的值而不是样式中指定的值。

我该如何解决这个问题?为什么会这样?

6 个答案:

答案 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/