2011-03-19 9 views
17

trato de cambiar la propiedad Background para mis ListBoxItem s utilizando factores desencadenantes en el ItemContainerStyle de mi ListBox de la siguiente manera:WPF: ¿se ListBoxItem.IsSelected que no trabaja para propiedad Background

<ListBox Height="100" HorizontalAlignment="Left" Margin="107,59,0,0" Name="listBox1" VerticalAlignment="Top" Width="239"> 
     <ListBox.ItemContainerStyle> 
      <Style TargetType="{x:Type ListBoxItem}"> 
       <Setter Property="Background" Value="Lightblue"/> 
       <Style.Triggers> 
        <Trigger Property="IsSelected" Value="true"> 
         <Setter Property="Background" Value="Red"/> 
        </Trigger> 
        <Trigger Property="IsMouseOver" Value="true"> 
         <Setter Property="Background" Value="Yellow"/> 
        </Trigger> 
       </Style.Triggers> 
      </Style> 
     </ListBox.ItemContainerStyle> 
     <ListBox.Items> 
      <ListBoxItem Content="First Item"/> 
      <ListBoxItem Content="SecondItem"/> 
      <ListBoxItem Content="Third Item"/> 
     </ListBox.Items> 
    </ListBox> 

Yo esperaría a los elementos no seleccionados tiene un fondo azul claro, los elementos al revés (es decir, cuando el cursor del mouse está sobre ellos) son amarillos y los elementos seleccionados son rojos.

Para los elementos no seleccionados y suspendidos, funciona como se esperaba, pero los elementos seleccionados siguen teniendo su color de fondo estándar (es decir, azul, si el cuadro de lista tiene el foco y gris claro en caso contrario).

¿Hay algo que me falta? ¿Este comportamiento está documentado en alguna parte?

¡Gracias por cualquier pista!

EDITAR

Soy consciente de la solución de anular el sistema de colores por defecto (como se describe en Change selected and unfocused Listbox style to not be grayed out, gracias de todos modos para todo el mundo publicar esto como una respuesta). Sin embargo, esto no es lo que quiero hacer. Estoy más interesado en por qué mi solución no funciona.

Estoy sospechando el estándar ControlTemplate de ListItem para definir su propio desencadenantes que parecen tener prioridad sobre las disparadores definidos por el estilo (tal vez alguien podría confirmar esto y me señale algún recurso donde se define este comportamiento).

Mi solución para el medio tiempo es definir un ControlTemplate para mis ListItem s como:

 <ListBox.ItemContainerStyle> 
      <Style TargetType="{x:Type ListBoxItem}"> 
       <Setter Property="Template"> 
        <Setter.Value> 
         <ControlTemplate TargetType="ListBoxItem"> 
          <Border Name="Border" Padding="2" SnapsToDevicePixels="true" Background="LightBlue" Margin="0"> 
           <ContentPresenter/> 
          </Border> 
          <ControlTemplate.Triggers> 
           <Trigger Property="IsSelected" Value="true"> 
            <Setter TargetName="Border" Property="Background" Value="Red"/> 
           </Trigger> 
          </ControlTemplate.Triggers> 
         </ControlTemplate> 
        </Setter.Value> 
       </Setter> 
      </Style> 
     </ListBox.ItemContainerStyle> 
+0

en este sentido, usted utiliza la solución correcta todavía. No hay solución con ControlTemplate estándar y sin sobreimpresión de pincel. – Sonorx

Respuesta

14

Un poco de reflexión sobre el estilo Aero nos ofrece una explicación de por qué este simple ajuste de gatillo no funciona.

ListBoxItem tiene una ControlTemplate con desencadenantes que tiene prioridad sobre nuestro desencadenador. Al menos esto parece ser cierto para un MultiTrigger. He logrado anular el disparador simple de Selected = true, pero para el multitrigger tuve que crear mi propia ControlTemplate.

Esta es la plantilla del estilo Aero que muestra la problemática MultiTrigger:

<ControlTemplate TargetType="{x:Type ListBoxItem}"> 
    <ControlTemplate.Triggers> 
     <Trigger Property="IsSelected" Value="true"> 
      <Setter TargetName="Bd" Value="{DynamicResource {x:Static HighlightBrush}}" Property="Background" /> 
      <Setter Value="{DynamicResource {x:Static HighlightTextBrush}}" Property="Foreground" /> 
     </Trigger> 
     <MultiTrigger> 
      <MultiTrigger.Conditions> 
       <Condition Property="IsSelected" Value="true" /> 
       <Condition Property="IsSelectionActive" Value="false" /> 
      </MultiTrigger.Conditions> 
      <Setter TargetName="Bd" Value="{DynamicResource {x:Static ControlBrush}}" Property="Background" /> 
      <Setter Value="{DynamicResource {x:Static ControlTextBrush}}" Property="Foreground" /> 
     </MultiTrigger> 
     <Trigger Property="IsEnabled" Value="false"> 
      <Setter Value="{DynamicResource {x:Static GrayTextBrush}}" Property="Foreground" /> 
     </Trigger> 
    </ControlTemplate.Triggers> 
    <Border Name="Bd" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true"> 
     <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" /> 
    </Border> 
</ControlTemplate> 

espero que aclara las cosas un poco. No puedo entender por qué han complicado demasiado el estilo.

4

Trate de añadir esto a sus recursos de ventanas -

<Window.Resources> 
      <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" 
          Color="Red" /> 
</Window.Resources> 

Y quitar el IsSelected gatillo de su código , no funcionará porque cada sistema tiene su pincel de resaltado predeterminado según el tema del sistema.

Debe sobrescribir el pincel de resaltado en su código para que funcione.

7

eliminar IsSelected gatillo Y añadir a cuadro de lista:

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

primer cepillo para el segundo enfocado pues de lo contrario

+0

No funciona tampoco para mí ._. –

0

Trate de usar Selector.IsSelected en su disparador en lugar de IsSelected.

+0

Esto no ayuda. – MartinStettner