【问题标题】:ListView Style Trigger affecting one control and not anotherListView 样式触发器影响一个控件而不是另一个
【发布时间】:2014-01-22 16:45:50
【问题描述】:

我有一个 ListView 控件,其中包含系统消息列表,以及一个相应的“操作”按钮,可以帮助我的用户解决消息:

如果消息是错误消息,我希望文本的前景和操作按钮([更多...] 部分)变为红色。如您所见,它没有这样做。

我正在使用绑定到消息数据严重性的 Style.Trigger 来设置前景。这适用于 DataTemplate 中的 TextBlock,但不会影响该模板中的 Button。我的 XAML 如下所示:

   <ListView x:Name="ImageCenterStatus" Background="{DynamicResource SC.ControlBrush}" Margin="10,22,10,0"  FontSize="12" Grid.Column="1" ClipToBounds="True" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <WrapPanel>
                        <TextBlock TextWrapping="WrapWithOverflow" cal:Message.Attach="[Event MouseUp] = [Action DoStatusAction($dataContext)]" Text="{Binding Path=DisplayedMessage}"/>
                        <Button x:Name="ActionButton" Content="{Binding Path=DisplayedActionLabel}" FontSize="12" cal:Message.Attach="DoStatusAction($dataContext)" Style="{DynamicResource SC.ActionButtonHack}"></Button>
                    </WrapPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Path=Severity}" Value="Warning">
                            <Setter Property="Foreground" Value="#FFCE7A16"  />
                        </DataTrigger>
                        <DataTrigger Binding="{Binding Path=Severity}" Value="Error">
                            <Setter Property="Foreground" Value="#FFD13636"  />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ListView.ItemContainerStyle>
        </ListView>

按钮有自己的样式,SC.ActionButtonHack,但我非常小心不要覆盖该样式的任何地方的前景:

            <Style x:Key="SC.ActionButtonHack" TargetType="{x:Type Button}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <ContentPresenter x:Name="contentPresenter" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0"/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

为什么DataTemplate中的TextBlock响应Trigger中的Foreground变化,而Button却没有响应? 我需要做什么才能让按钮尊重前台更改?

【问题讨论】:

  • 你的SC.ActionButtonHack Style到底是干什么用的?
  • 用于测试目的。我有一个更复杂的风格,但我将其剥离以保持这篇文章的简短。
  • 这似乎很公平。

标签: wpf listview foreground


【解决方案1】:

将 ContentPresenter 的 TextElement.Foreground 绑定到 ListViewItem's foreground 以使其工作:

<Style x:Key="SC.ActionButtonHack" TargetType="{x:Type Button}">
    <Setter Property="Template">
       <Setter.Value>
          <ControlTemplate TargetType="{x:Type Button}">
              <ContentPresenter x:Name="contentPresenter"
                                TextElement.Foreground="{Binding Foreground, 
                                RelativeSource={RelativeSource Mode=FindAncestor,
                                                  AncestorType=ListViewItem}}"
                                HorizontalAlignment="Center"
                               VerticalAlignment="Center" Margin="0"/>
          </ControlTemplate>
       </Setter.Value>
    </Setter>
</Style>

将其绑定到 Button 本身:

<Button x:Name="ActionButton"
        Foreground="{Binding Foreground, RelativeSource={RelativeSource 
                         Mode=FindAncestor, AncestorType=ListViewItem}}"
        Content="{Binding Path=Name}" FontSize="12"
        Style="{DynamicResource SC.ActionButtonHack}"/>

【讨论】:

  • 解决了!非常感谢。那么...为什么样式触发器适用于 TextBlock 而不是 Button?
  • 如果你查看按钮的默认 controlTemplate,你会发现它在其模板中为前景属性设置了默认值,其优先级高于属性值继承,这就是它不从其父 ListViewItem 继承的原因.阅读更多关于 DP 值优先顺序的信息here
  • 但是我不是在我的风格中覆盖默认的 ControlTemplate 吗?默认值怎么会影响到这一点?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多