web-dev-qa-db-fra.com

Modifier la couleur d'arrière-plan de l'élément ListBox sélectionné

Ceci est mon XAML jusqu'à présent.

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

Le seul problème est que l'élément sélectionné a une boîte bleue à droite. Je suppose qu'il y a un moyen de changer la couleur de sélection, mais je ne la trouve pas.

60
Jonathan Allen

Vous devez utiliser ListBox.ItemContainerStyle .

ListBox.ItemTemplate spécifie comment le contenu d'un élément doit être affiché. Mais WPF encapsule toujours chaque élément dans un contrôle ListBoxItem, qui par défaut obtient son arrière-plan défini sur la couleur de surbrillance du système s'il est sélectionné. Vous ne pouvez pas empêcher WPF de créer les contrôles ListBoxItem, mais vous pouvez les styler - dans votre cas, pour définir l'arrière-plan sur toujours Transparent ou Noir -, et pour ce faire, vous utilisez ItemContainerStyle.

réponse de juFo montre une implémentation possible, en "détournant" la ressource brosse de fond du système dans le contexte du style d'élément; Une autre technique, peut-être plus idiomatique, consiste à utiliser un Setter pour la propriété Background.

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

et

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

Vous venez de remplacer le style du listboxitem (voir le: TargetType est ListBoxItem)

73
juFo

Ou vous pouvez appliquer HighlightBrushKey directement au ListBox. Setter Property = "Background" Value = "Transparent" ne fonctionnait PAS. Mais je devais définir le premier plan en noir.

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

Je devais régler HighlightBrushKey et ControlBrushKey pour que le style soit correct. Autrement, tant qu'il aura le focus, il utilisera correctement le transparent HighlightBrusKey. Bt, si le contrôle perd le focus (alors qu'il est toujours en surbrillance), il utilise ControlBrushKey.

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

Lorsque vous utilisez .Net 4.5 et supérieur, utilisez InactiveSelectionHighlightBrushKey au lieu de ControlBrushKey:

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

J'espère que cela aide quelqu'un.

30
RichS

Vous devez créer un nouveau modèle pour la sélection d'éléments comme ceci.

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

Si la sélection n'est pas importante, il est préférable d'utiliser un élément ItemsControl entouré d'un objet ScrollViewer. Cette combinaison est plus légère que la Listbox (qui est en fait déjà dérivée de ItemsControl) et son utilisation éliminerait la nécessité d’utiliser un piratage économique pour remplacer le comportement déjà absent de ItemsControl.

Dans les cas où le comportement de sélection IS est en fait important, cela ne fonctionnera évidemment pas. Toutefois, si vous souhaitez modifier la couleur de l'arrière-plan de l'élément sélectionné de manière à ce qu'il ne soit pas visible Si vous avez l’intention de modifier une autre caractéristique pour indiquer que l’article est sélectionné, certaines des autres réponses à cette question risquent d’être encore plus pertinentes.

Voici un squelette de l'apparence du balisage:

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