4

我还在学习 Blend,所以请多多包涵。我在 WPF 项目中有一个切换按钮,我需要更改不同状态的文本颜色,例如鼠标悬停和选中。但是,当我编辑模板并选择 contentPresenter 时,唯一的画笔是 OpacityMask,它不受任何画笔颜色更改的影响。

我当然可以通过编辑样式来更改文本颜色,但这没有用,因为它在我感兴趣的编辑状态内。

基本上,我只是想让按钮的文本在鼠标悬停、悬停等时改变,这似乎是一个合理的做法,但 ContentPresenter 的 OpacityMask Brush 无法编辑。

有人提到将 ContentPresenter 更改为 ContentControl。这确实有效,但我现在无法编辑按钮实例的文本。我是否必须将 ContentControl 链接到某些东西?

非常感谢您的帮助。我被困在这里几个小时,我一直在到处寻找答案,但无济于事

4

2 回答 2

1

前台属性存在于样式中。所以你可以编辑 Style 并在那里你可以设置Foreground. 它可能是这样的

<Style.Triggers>
    <Trigger Property="IsChecked" Value="False">
        <Setter Property="Foreground" Value="Blue"/>
    </Trigger>
</Style.Triggers>

或者如果你想改变它,ControlTemplate那么你可以这样做。

<Trigger Property="IsChecked" Value="True">
   <Setter Property="TextBlock.Foreground" TargetName="contentPresenterName" Value="White"/>
</Trigger>

所以在表达混合中你这样做

  1. 在资源面板中找到您的样式,然后单击资源旁边的编辑资源按钮。或者右键单击并选择Edit
  2. 在触发器面板中添加触发器。
  3. 转到属性面板并更改前景属性。
于 2013-07-09T09:20:14.620 回答
1

你可以做你正在寻找的东西,而无需使用 aContentControl并且只需使用VisualStateManager

我当然可以通过编辑样式来更改文本颜色,但这没有用,因为它在我感兴趣的编辑状态内。

因此,例如将新Foreground颜色应用于您的文本的状态ButtonMouseOver

  • 首先,Blend在编辑模板时不会创建Brush资源。Button.MouseOver.ForegroundButton

所以让我们创建一个。(只需添加以下行以及其他画笔资源)

<SolidColorBrush x:Key="Button.MouseOver.Foreground" Color="Tomato" />
  • 现在我们可以将 aStoryboard应用于TextElement.Foreground.contentPresenter

所以你的 VSM 看起来像:

<VisualStateManager.VisualStateGroups>
    <VisualStateGroup x:Name="CommonStates">
        <VisualState x:Name="Normal"/>
        <VisualState x:Name="MouseOver">
      <Storyboard>
        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="contentPresenter"
                                        Storyboard.TargetProperty="(TextElement.Foreground)">
          <DiscreteObjectKeyFrame KeyTime="0">
            <DiscreteObjectKeyFrame.Value>
              <SolidColorBrush Color="{Binding Source={StaticResource Button.MouseOver.Foreground}, Path=Color}" />
            </DiscreteObjectKeyFrame.Value>
          </DiscreteObjectKeyFrame>
        </ObjectAnimationUsingKeyFrames>
      </Storyboard>
        </VisualState>
        <VisualState x:Name="Pressed"/>
        <VisualState x:Name="Disabled"/>
    </VisualStateGroup>
</VisualStateManager.VisualStateGroups>

就是这样。

请注意,仅当 的Content只是文本时,我们在这里所做的事情才可以Button,但是由于这就是您的问题中提到的用法,因此您应该没问题。

边注:

您只需ContentPresenterTextBlock.ControlTemplate

如果您需要Foreground可用于任何ContentButton那么您只需将 切换ContentPresenter到 a ContentControl,您仍然可以以非常相似的方式使用您的 VSM Storyboard。

更新

要切换ContentPresenter到 a ContentControlControlTemplate只需将实际元素切换为新元素即可。

<ControlTemplate TargetType="{x:Type Button}">
  ...
  <ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" RecognizesAccessKey="True"/>
  ...
</ControlTemplate>

到:

<ControlTemplate TargetType="{x:Type Button}">
  ...
  <ContentControl x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Content="{TemplateBinding Content}"/>
  ...
</ControlTemplate>

您必须相应地更新它们的属性,例如ContentControl不支持RecognizesAccessKeys,并且还需要Content="{TemplateBinding Content}"对其进行设置以实际显示内容。使用 a隐式设置属性ContentPresenterContent

于 2013-07-09T10:47:32.977 回答