2010-01-26 29 views
55

Este es mi XAML hasta ahora.Cambiar el color de fondo para el elemento de ListBox seleccionado

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

El único problema es que el elemento seleccionado tiene un cuadro azul a la derecha. Supongo que hay una forma de cambiar el color de selección, pero no puedo encontrarlo.

Respuesta

38

Es necesario utilizar ListBox.ItemContainerStyle.

ListBox.ItemTemplate especifica cómo debe mostrarse el contenido de un elemento. Pero WPF todavía envuelve cada elemento en un control ListBoxItem, que de forma predeterminada obtiene su fondo establecido en el color de resaltado del sistema, si está seleccionado. No puede evitar que WPF cree los controles ListBoxItem, pero puede personalizarlos, en su caso, para configurar el fondo para que siempre sea transparente o negro o lo que sea, y para hacerlo, use ItemContainerStyle.

juFo's answer muestra una posible implementación, mediante el "secuestro" del recurso de pincel de fondo del sistema en el contexto del estilo del elemento; otra técnica, quizás más idiomática, es usar Setter para la propiedad Background.

+0

Ok, ahora tiene mucho más sentido. Gracias. –

+0

No funciona si solo usa un 'Setter' para la propiedad 'Background' en 'IsSelected' es verdadero en ItemContainerStyle. Todavía usa el color de resaltado del sistema. :( – user1108069

+0

Para cambiar el color de fondo del elemento ListBoxItem seleccionado, debe volver a aplicar el elemento ListBox. Ref: el comentario en la respuesta aceptada en [aquí] (http://stackoverflow.com/questions/7059526/set-background-color- for-selected-items-in-a-listbox). VS 2012, .Net Framework 4.5. – user1108069

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

y

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

Usted acaba de anular el estilo de la ListBoxItem (véase el: TargetType es ListBoxItem)

+15

Esto ya no se aplica a Windows-8 que usa colores estáticos en los activadores 'ControlTemplate'. Tendría que derivar el 'Style' básico y especificar los pinceles superpuestos en esos disparadores o dar los colores directamente. http://stackoverflow.com/a/16820062/1834662 – Viv

+1

gracias por compartir esto @Viv – juFo

+0

@Viv ¿Esto también se aplica a wpf en .net 4.5? – Gusdor

48

O puede aplicar HighlightBrushKey directamente al ListBox. Setter Property = "Background" Value = "Transparent" NO funcionó. Pero tuve que configurar el primer plano en negro.

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

Abajo atención de voto para explicar – Paparazzi

+0

esta solución funciona para mí, pero la respuesta de @ juFo no es correcta, porque todo el control da transparencia. no veo ningún texto. – IFink

29

Tuve que configurar tanto HighlightBrushKey como ControlBrushKey para que se personalizara correctamente. De lo contrario, mientras tenga foco, usará correctamente la tecla HighlightBrusKey transparente. Bt, si el control pierde el foco (mientras todavía está resaltado), entonces usa la tecla ControlBrush.

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

Espero que esto ayude a alguien.

+0

Esto me ayudó mucho. No sabía qué era el cepillo SystemColors utilizado cuando el ListBox no estaba enfocado :) +1 – Kyopaxa

+0

Esto fue fundamental para que el fondo fuera transparente al seleccionar botón derecho del ratón. ¡Gracias! –

+15

Use InactiveSelectionHighlightBrushKey en lugar de ControlBrushKey desde .NET 4.5. –

7

Si la selección no es importante, es mejor usar un ItemsControl envuelto en un ScrollViewer. Esta combinación es más liviana que el Listbox (que en realidad se deriva de ItemsControl ya) y su uso eliminaría la necesidad de utilizar un hack barato para anular el comportamiento que ya está ausente de ItemsControl.

En los casos donde el comportamiento de selección ES realmente importante, obviamente esto no funcionará. Sin embargo, si desea cambiar el color del Fondo del elemento seleccionado de tal manera que no sea visible para el usuario, eso solo serviría para confundirlos. En los casos donde su intención es cambiar alguna otra característica para indicar que el elemento está seleccionado, algunas de las otras respuestas a esta pregunta pueden ser aún más relevantes.

Aquí es un esqueleto de cómo el marcado debe ser:

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

Tienes que crear una nueva plantilla para la selección artículo como éste.

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

Una buena respuesta es más que una respuesta de trabajo, el OP debe entender su error en lugar de copiarlo pegándolo. De lo contrario, volverá una semana más tarde haciendo la misma pregunta en un contexto diferente ... – ShellFish

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

Este código funcionó como un encanto para mí. Gracias al cartel original.

Cuestiones relacionadas