Изменить цвет фона для выбранного элемента ListBox

Это мой 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>

Единственная проблема заключается в том, что выбранный элемент имеет синее поле справа. Я предполагаю, что есть способ изменить цвет выделения, но я не могу его найти.

6 ответов

Решение

Вам нужно использовать ListBox.ItemContainerStyle.

ListBox.ItemTemplate указывает, как должно отображаться содержимое элемента. Но WPF по-прежнему оборачивает каждый элемент в элемент управления ListBoxItem, который по умолчанию получает свой цвет фона, установленный в системном цвете подсветки, если он выбран. Вы не можете остановить WPF, создавая элементы управления ListBoxItem, но вы можете стилизовать их - в вашем случае, чтобы установить для фона всегда прозрачный или черный или любой другой тип - и для этого вы используете ItemContainerStyle.

Ответ juFo показывает одну из возможных реализаций путем "захвата" ресурса системной кисти в контексте стиля элемента; другой, возможно, более идиоматический метод заключается в использовании Setter для свойства Background.

<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}">  

Вы просто переопределяете стиль элемента списка (см.: TargetType is ListBoxItem)

Или вы можете применить 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>

Мне нужно было установить и HighlightBrushKey, и ControlBrushKey, чтобы правильно его стилизовать. В противном случае, хотя он имеет фокус, он будет правильно использовать прозрачный HighlightBrusKey. Bt, если элемент управления теряет фокус (хотя он все еще выделен), тогда он использует ControlBrushKey.

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

Надеюсь, это поможет кому-то.

Я пробовал различные решения, и ни одно из них не помогло мне, после еще нескольких исследований я нашел решение, которое сработало для меня здесь

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>

Я разместил его здесь, так как это первый результат Google по этой проблеме, поэтому некоторые другие могут найти его полезным.

Вы должны создать новый шаблон для выбора элемента, как это.

<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>

Если выбор не важен, лучше использовать ItemsControl, завернутый в ScrollViewer. Эта комбинация является более легкой, чем Listbox (который на самом деле является производным от ItemsControl), и ее использование избавит от необходимости использовать дешевый хак для переопределения поведения, которое уже отсутствует в ItemsControl.

В случаях, когда поведение выбора действительно важно, тогда это, очевидно, не будет работать. Однако, если вы хотите изменить цвет фона выбранного элемента таким образом, чтобы он не был виден пользователю, то это могло бы только ввести их в заблуждение. В тех случаях, когда вы намерены изменить какую-либо другую характеристику, чтобы указать, что элемент выбран, тогда некоторые другие ответы на этот вопрос могут все еще быть более актуальными.

Вот скелет того, как должна выглядеть разметка:

    <ScrollViewer>
        <ItemsControl>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    ...
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </ScrollViewer>
<Style.Resources>
    <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent"/>
</Style.Resources>

Этот код работал для меня как шарм. Спасибо оригинальному постеру.

Другие вопросы по тегам