Najłatwiejszym sposobem jest dostarczenie szablonu dla właściwości „ItemContainerStyle”, a NIE właściwości „ItemTemplate”. W poniższym kodzie tworzę 2 szablony danych: jeden dla stanów „niewybranych” i jeden dla stanów „zaznaczonych”. Następnie tworzę szablon dla „ItemContainerStyle”, który jest rzeczywistym „ListBoxItem” zawierającym element. Ustawiam domyślny „ContentTemplate” na stan „Unselected”, a następnie podaję wyzwalacz, który zamienia szablon, gdy właściwość „IsSelected” ma wartość true. (Uwaga: ustawiam właściwość „ItemsSource” w kodzie za listą ciągów dla uproszczenia)
<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}}"
z ListBox. Dotyczy to również innych kontrolek, takich jak TreeView.Aby ustawić styl, gdy element jest zaznaczony lub nie wszystko, co musisz zrobić, to odzyskać
ListBoxItem
rodzica w swoim<DataTemplate>
i wywołać zmiany stylu, gdy sięIsSelected
zmieni. Na przykład poniższy kod utworzyTextBlock
domyślnyForeground
kolor zielony . Teraz, jeśli element zostanie wybrany, czcionka zmieni kolor na czerwony, a gdy wskaźnik myszy znajdzie się nad elementem, zmieni kolor na żółty . W ten sposób nie musisz określać oddzielnych szablonów danych, jak sugerują inne odpowiedzi dla każdego stanu, który chcesz nieznacznie zmienić.<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>
źródło
Należy również zauważyć, że panel stosu nie jest focu-up, więc nigdy nie zostanie skupiony (ustaw Focusable = True, jeśli chcesz / naprawdę / chcesz, aby był skupiony). Jednak kluczem do zapamiętania w scenariuszach takich jak ten jest to, że Stackpanel jest elementem podrzędnym TreeViewItem, który w tym przypadku jest ItemContainer. Jak sugeruje Micah, poprawienie stylu pojemnika na przedmioty to dobre podejście.
Prawdopodobnie mógłbyś to zrobić za pomocą DataTemplates i rzeczy takich jak datatriggers, które używałyby rozszerzenia znaczników RelativeSouce do wyszukiwania elementu listviewitem
źródło