La forma más sencilla de hacer esto es proporcionar una plantilla para el "ItemContainerStyle" y NO la propiedad "ItemTemplate". En el siguiente código, creo 2 plantillas de datos: una para los estados "no seleccionados" y otra para los estados "seleccionados". Luego creo una plantilla para el "ItemContainerStyle" que es el "ListBoxItem" real que contiene el elemento. Establezco el "ContentTemplate" predeterminado en el estado "No seleccionado" y luego proporciono un activador que cambia la plantilla cuando la propiedad "IsSelected" es verdadera. (Nota: estoy configurando la propiedad "ItemsSource" en el código subyacente a una lista de cadenas para simplificar)
<Window.Resources>
<DataTemplate x:Key="ItemTemplate">
<TextBlock Text="{Binding}" Foreground="Red" />
</DataTemplate>
<DataTemplate x:Key="SelectedTemplate">
<TextBlock Text="{Binding}" Foreground="White" />
</DataTemplate>
<Style TargetType="{x:Type ListBoxItem}" x:Key="ContainerStyle">
<Setter Property="ContentTemplate" Value="{StaticResource ItemTemplate}" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="ContentTemplate" Value="{StaticResource SelectedTemplate}" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<ListBox x:Name="lstItems" ItemContainerStyle="{StaticResource ContainerStyle}" />
BasedOn="{StaticResource {x:Type ListBoxItem}}"
con ListBox. Esto también se aplica a otros controles como TreeView.Para establecer el estilo cuando el elemento está seleccionado o no, todo lo que necesita hacer es recuperar el
ListBoxItem
padre en su<DataTemplate>
y activar cambios de estilo cuandoIsSelected
cambie. Por ejemplo, el siguiente código creará un color verdeTextBlock
predeterminado . Ahora, si el elemento se selecciona, la fuente se volverá roja y cuando el mouse esté sobre el elemento se volverá amarillo . De esa manera, no es necesario que especifique plantillas de datos separadas como se sugiere en otras respuestas para cada estado que le gustaría cambiar ligeramente.Foreground
<DataTemplate x:Key="SimpleDataTemplate"> <TextBlock Text="{Binding}"> <TextBlock.Style> <Style> <Setter Property="TextBlock.Foreground" Value="Green"/> <Style.Triggers> <DataTrigger Binding="{Binding Path=IsSelected, RelativeSource={ RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem }}}" Value="True"> <Setter Property="TextBlock.Foreground" Value="Red"/> </DataTrigger> <DataTrigger Binding="{Binding Path=IsMouseOver, RelativeSource={ RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem }}}" Value="True"> <Setter Property="TextBlock.Foreground" Value="Yellow"/> </DataTrigger> </Style.Triggers> </Style> </TextBlock.Style> </TextBlock> </DataTemplate>
fuente
También debe tenerse en cuenta que el panel de pila no se puede enfocar, por lo que nunca se enfocará (establezca Focusable = True si usted / realmente / quiere que esté enfocado). Sin embargo, la clave para recordar en escenarios como este es que el Stackpanel es hijo del TreeViewItem, que es el ItemContainer en este caso. Como sugiere Micah, modificar el estilo del contenedor de elementos es un buen enfoque.
Probablemente podría hacerlo usando DataTemplates y cosas como datatriggers que usarían la extensión de marcado RelativeSouce para buscar el elemento listview
fuente