.net - tutorial - Cambie WPF DataTemplate para el elemento ListBox si está seleccionado
wpf vs winforms (3)
La forma más sencilla de hacerlo es proporcionar una plantilla para la propiedad "ItemContainerStyle" y NO la propiedad "ItemTemplate". En el código siguiente, creo 2 plantillas de datos: una para los estados "no seleccionado" y otra para los estados "seleccionados". Luego creo una plantilla para el "ItemContainerStyle" que es el "ListBoxItem" actual que contiene el artículo. Establecí el valor predeterminado "ContentTemplate" en el estado "No seleccionado" y luego proporciono un activador que intercambia la plantilla cuando la propiedad "IsSelected" es verdadera. (Nota: estoy configurando la propiedad "ItemsSource" en el código detrás de 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}" />
Necesito cambiar DataTemplate para elementos en un ListBox dependiendo de si el elemento está seleccionado o no (mostrando diferente / más información cuando se selecciona).
No obtengo un evento GotFocus / LostFocus en el elemento superior de DataTemplate (un StackPanel) al hacer clic en el elemento de ListBox en cuestión (solo a través de tabulaciones), y me quedo sin ideas.
Para establecer el estilo cuando se selecciona el elemento o no, todo lo que tiene que hacer es recuperar el ListBoxItem
primario ListBoxItem
en su <DataTemplate>
y activar los cambios de estilo cuando se cambie IsSelected
. Por ejemplo, el código siguiente creará un TextBlock
con color de Foreground
predeterminado en verde . Ahora, si se selecciona el elemento, la fuente se pondrá roja y cuando el mouse haya terminado, el elemento se pondrá amarillo . De esta forma, no es necesario que especifique plantillas de datos separadas como se sugiere en otras respuestas para cada estado que desee cambiar ligeramente.
<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>
También se debe tener en cuenta que el panel de distribución no es focable, por lo que nunca se enfocará (establecer Enfocable = Verdadero si usted / realmente / desea enfocar). Sin embargo, la clave para recordar en escenarios como este es que Stackpanel es hijo del TreeViewItem, que es el ItemContainer en este caso. Como sugiere Micah, ajustar el estilo del elemento contenedor es un buen enfoque.
Probablemente puedas hacerlo usando DataTemplates, y cosas como los activadores de datos que usarían la extensión de marcado RelativeSouce para buscar el listviewitem