Change WPF DataTemplate for ListBox if it is selected

I need to change the DataTemplate for items in a ListBox depending on whether the item is selected or not (different / additional information is displayed when selected).

I don't get the GotFocus / LostFocus event in the topmost DataTemplate (StackPanel) when I click on the ListBox (only through tabbing) and I have no ideas.

+82
wpf
Sep 28 '08 at 17:10
source share
3 answers

The easiest way to do this is to provide a template for the "ItemContainerStyle" property and NOT the "ItemTemplate". In the code below, I create 2 data patterns: one for the “unselected” and one for the “selected” states. Then I create a template for the "ItemContainerStyle", which is the actual "ListBoxItem" that contains the item. I set the default "ContentTemplate" to "Unselected" and then provided a trigger that changes the pattern when the IsSelected property is true. (Note: I set the “ItemsSource” property in the code behind the list of strings for simplicity)

<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}" /> 
+166
Sep 28 '08 at 18:25
source share

It should also be noted that the stack panel is not valid, so it will never receive focus (set Focusable = True if you / really / want it to focus). However, the key to remembering in scenarios like this is that the Stackpanel is a child of the TreeViewItem, which in this case is an ItemContainer. According to Mika, fine-tuning the style of the container is a good approach.

Perhaps you could do this with DataTemplates and things like datatriggers that will use the RelativeSouce markup extension to search for listviewitem

+6
Sep 28 '08 at 21:05
source share

To set the style when an item is selected or not all you need to do is restore the parent ListBoxItem to <DataTemplate> and change the startup style when its IsSelected . For example, the code below will create a TextBlock with the default Foreground color green . Now, if an element is selected, the font will turn red , and when the mouse is finished, the element will turn yellow . This way, you do not need to specify separate data patterns, as suggested in the other answers for each state that you want to slightly change.

 <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> 
+5
Dec 23 '14 at 4:48
source share



All Articles