【问题标题】:Change background color for selected ListBox item更改选定列表框项目的背景颜色
【发布时间】:2011-01-09 10:33:48
【问题描述】:

到目前为止,这是我的 XAML。

<ScrollViewer Grid.Column="1" Grid.RowSpan="2">

    <ListBox   Background="Black" ItemsSource="{Binding Path=ActiveLog}" >
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Grid Background="Black">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="200"></ColumnDefinition>
                        <ColumnDefinition Width="*"></ColumnDefinition>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition></RowDefinition>
                        <RowDefinition></RowDefinition>
                    </Grid.RowDefinitions>
                    <TextBlock Grid.Column="0" Grid.Row="0" Foreground="White">
                        <TextBlock >Date:</TextBlock>
                        <TextBlock  Text="{Binding Path=LogDate}"/>
                    </TextBlock>
                    <TextBlock Grid.Column="1" Grid.Row="0" Foreground="White">
                        <TextBlock >Severity:</TextBlock>
                        <TextBlock  Text="{Binding Path=Severity}"/>
                    </TextBlock>
                    <TextBlock Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1" Foreground="LightGray" Text="{Binding Path=Message}"></TextBlock>
                </Grid>
            </DataTemplate>
        </ListBox.ItemTemplate>
        <ListBox.Template>
            <ControlTemplate>
                <StackPanel Background="Black" IsItemsHost="True" >
                </StackPanel>
            </ControlTemplate>
        </ListBox.Template>

    </ListBox>
</ScrollViewer>

唯一的问题是所选项目的右侧有一个蓝色框。我认为有一种方法可以更改选择颜色,但我找不到它。

【问题讨论】:

    标签: wpf styles


    【解决方案1】:
    <UserControl.Resources>
        <Style x:Key="myLBStyle" TargetType="{x:Type ListBoxItem}">
            <Style.Resources>
                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
                                 Color="Transparent"/>
            </Style.Resources>
        </Style>
    </UserControl.Resources> 
    

    <ListBox ItemsSource="{Binding Path=FirstNames}"
             ItemContainerStyle="{StaticResource myLBStyle}">  
    

    你只是覆盖了listboxitem的样式(见:TargetType is ListBoxItem)

    【讨论】:

    • 这不再适用于在 ControlTemplate 触发器中使用静态颜色的 Windows-8。您必须派生基础 Style 并在这些触发器中指定覆盖的画笔或直接提供颜色。 stackoverflow.com/a/16820062/1834662
    • @Viv 这是否也适用于 .net 4.5 中的 wpf?
    • @Gusdor 是的,对于 Windows-7 上的 .net4.5,ControlTemplate 使用 SystemColors 表示状态。但是在 Windows-8 中,它不再像 Here 解释的那样。每个操作系统版本的差异似乎比每个 .net 版本的差异更大
    【解决方案2】:

    或者您可以将 HighlightBrushKey 直接应用到 ListBox。 Setter Property="Background" Value="Transparent" 不起作用。但我确实必须将前景设置为黑色。

    <ListBox  ... >
        <ListBox.ItemContainerStyle>
            <Style TargetType="ListBoxItem">
                <Style.Triggers>
                    <Trigger Property="IsSelected" Value="True" >
                        <Setter Property="FontWeight" Value="Bold" />
                        <Setter Property="Background" Value="Transparent" />
                        <Setter Property="Foreground" Value="Black" />
                    </Trigger>
                </Style.Triggers>
                <Style.Resources>
                    <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent"/>
                </Style.Resources>
            </Style>                
        </ListBox.ItemContainerStyle>
    </ListBox>
    

    【讨论】:

    • 这个解决方案对我有用,但@juFo 的答案并不奏效,因为所有控件都提供透明,看不到任何文本。
    【解决方案3】:

    您需要使用ListBox.ItemContainerStyle

    ListBox.ItemTemplate 指定项目的内容 应如何显示。但 WPF 仍将每个项目包装在 ListBoxItem 控件中,如果选中,默认情况下,该控件会将其背景设置为系统突出显示颜色。您无法停止 WPF 创建 ListBoxItem 控件,但您可以设置它们的样式 - 在您的情况下,将背景设置为始终为透明或黑色或其他 - 为此,您可以使用 ItemContainerStyle。

    juFo's answer 展示了一种可能的实现方式,即在项目样式的上下文中“劫持”系统背景画笔资源;另一种可能更惯用的技术是使用 Setter 作为 Background 属性。

    【讨论】:

    • 好的,现在更有意义了。谢谢。
    • 如果在 ItemContainerStyle 中只为 'IsSelected' 中的 'Background' 属性使用 'Setter' 则不起作用。它仍然使用系统突出显示颜色。 :(
    • 要更改所选ListBoxItem的背景颜色,您需要重新模板ListBoxItem。参考:here 中接受的答案中的评论。 VS 2012,.Net 框架 4.5。
    • 您能否提供一个基于 ListBox.ItemContainerStyle 的解决方案的工作示例?似乎它不起作用,唯一可行的解​​决方案(不是基于系统颜色)是重新模板。
    【解决方案4】:

    我必须同时设置 HighlightBrushKey 和 ControlBrushKey 才能正确设置样式。否则,虽然它有焦点,但它将正确使用透明的 HighlightBrusKey。顺便说一句,如果控件失去焦点(但仍突出显示),则它使用 ControlBrushKey。

    <Style.Resources>
        <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent" />
        <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent" />
    </Style.Resources>
    

    使用 .Net 4.5 及更高版本时,请使用 InactiveSelectionHighlightBrushKey 而不是 ControlBrushKey

    <Style.Resources>
        <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent" />
        <SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="Transparent" />
    </Style.Resources>
    

    希望这对某人有所帮助。

    【讨论】:

    • 这对我帮助很大。我不知道 ListBox 没有聚焦时使用的 SystemColors 画笔是什么:) +1
    • 这对我在右键单击时使背景透明非常重要。谢谢!
    • 使用 InactiveSelectionHighlightBrushKey 而不是 .NET 4.5 中的 ControlBrushKey。
    【解决方案5】:

    您必须像这样为项目选择创建一个新模板。

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ListBoxItem">
                <Border
                    BorderThickness="{TemplateBinding Border.BorderThickness}"
                    Padding="{TemplateBinding Control.Padding}"
                    BorderBrush="{TemplateBinding Border.BorderBrush}"
                    Background="{TemplateBinding Panel.Background}"
                    SnapsToDevicePixels="True">
                    <ContentPresenter
                        Content="{TemplateBinding ContentControl.Content}"
                        ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
                        HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
                        VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}"
                        SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    

    【讨论】:

    • 一个好的答案不仅仅是一个有效的答案,OP应该理解他的错误,而不是仅仅复制粘贴。否则他/她会在一周后回来在不同的环境中问同样的问题......
    【解决方案6】:

    如果选择不重要,最好使用包装在 ScrollViewer 中的 ItemsControl。这种组合比 Listbox(实际上已经从 ItemsControl 派生)更轻量级,并且使用它可以消除使用廉价 hack 来覆盖 ItemsControl 中已经不存在的行为的需要。

    如果选择行为实际上很重要,那么这显然行不通。但是,如果您想以一种对用户不可见的方式更改所选项目背景的颜色,那么这只会使他们感到困惑。如果您打算更改某些其他特征以表明该项目已被选中,那么此问题的其他一些答案可能仍然更相关。

    这是标记的外观骨架:

        <ScrollViewer>
            <ItemsControl>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        ...
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </ScrollViewer>
    

    【讨论】:

      【解决方案7】:

      我尝试了各种解决方案,但没有一个适合我,经过更多研究后,我在这里找到了适合我的解决方案

      https://gist.github.com/LGM-AdrianHum/c8cb125bc493c1ccac99b4098c7eeb60

         <Style x:Key="_ListBoxItemStyle" TargetType="ListBoxItem">
                  <Setter Property="Template">
                      <Setter.Value>
                          <ControlTemplate TargetType="ListBoxItem">
                              <Border Name="_Border"
                                      Padding="2"
                                      SnapsToDevicePixels="true">
                                  <ContentPresenter />
                              </Border>
                              <ControlTemplate.Triggers>
                                  <Trigger Property="IsSelected" Value="true">
                                      <Setter TargetName="_Border" Property="Background" Value="Yellow"/>
                                      <Setter Property="Foreground" Value="Red"/>
                                  </Trigger>
                              </ControlTemplate.Triggers>
                          </ControlTemplate>
                      </Setter.Value>
                  </Setter>
              </Style>
      
       <ListBox ItemContainerStyle="{DynamicResource _ListBoxItemStyle}"
                       Width="200" Height="250"
                       ScrollViewer.VerticalScrollBarVisibility="Auto"
                       ScrollViewer.HorizontalScrollBarVisibility="Auto">
                  <ListBoxItem>Hello</ListBoxItem>
                  <ListBoxItem>Hi</ListBoxItem>
              </ListBox>
      

      我把它贴在这里,因为这是这个问题的第一个谷歌结果,所以其他人可能会觉得它很有用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-01-15
        • 1970-01-01
        • 2015-05-17
        • 2012-10-01
        • 2012-10-23
        • 1970-01-01
        相关资源
        最近更新 更多