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


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

6 ответов:

вы должны использовать списка.ItemContainerStyle.

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

ответ ЮФО показывает одну возможную реализацию, "захватывая" системный фоновый ресурс кисти в контексте стиля элемента; другой, возможно, более идиоматический метод заключается в использовании 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}">  

вы просто переопределяете стиль listboxitem (см.: TargetType is ListBoxItem)

или вы можете применить HighlightBrushKey непосредственно к списку. 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>

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

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

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

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

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

вы должны создать новый шаблон для выбора товаров такой.

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