In my WPF app (.NET 6.0) I have an ItemContainerStyle
for a ListBoxItem
that I've used successfully on ListBox
es for some time. But just today I tried to use it on a ListBox
where I also set the ItemTemplateSelector
property. I discovered that my style causes the selector to simply be ignored.
There are no warning or error messages in the debugger output window and no exceptions are thrown. Its just that the SelectTemplate
method is never called. So I end up with a box full of text class names. But if I remove the ItemContainerStyle
from the ListBox
, everything works and, SelectTemplate
is called for each item. But then my ListBoxItem
s don't look the way I want them to.
Below is my ItemContainerStyle
. I was easily able to reproduce the same effect in a test application as long as I used this ItemContainerStyle
on the ListBox. Can anyone figure out what there is in that might cause the ItemTemplateSelector
to simply be ignored?
<Style x:Key="ListBoxItemStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="Padding" Value="3,0,3,0" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Top" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Foreground" Value="{StaticResource GsForegroundLight}" />
<Setter Property="KeyboardNavigation.TabNavigation" Value="Local" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Grid>
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="1"
SnapsToDevicePixels="True" />
<!-- MouseOver Visual is exactly like Selected Visual (below) minus the rounded corners -->
<Border
x:Name="MouseOverVisual"
BorderBrush="{StaticResource GsForegroundLight}"
BorderThickness="1"
CornerRadius="3"
Opacity="0"
SnapsToDevicePixels="True">
<Border BorderThickness="1" CornerRadius="3" SnapsToDevicePixels="True">
<Border.Background>
<LinearGradientBrush Opacity="0.5" StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Offset="1" Color="{StaticResource GsBackgroundDarkColor}" />
<GradientStop Color="Gray" />
</LinearGradientBrush>
</Border.Background>
</Border>
</Border>
<!-- Selected Visual uses no border but just a gradient background brush -->
<Border x:Name="SelectedVisual"
BorderThickness="0"
CornerRadius="3"
Opacity="0"
SnapsToDevicePixels="True">
<Border
BorderBrush="Black"
BorderThickness="1"
CornerRadius="3"
SnapsToDevicePixels="True">
<Border.Background>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<GradientStop Offset="1" Color="{StaticResource GsBackgroundDarkColor}" />
<GradientStop Color="Gray" />
</LinearGradientBrush>
</Border.Background>
</Border>
</Border>
<ContentPresenter x:Name="contentPresenter"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Content}"
ContentStringFormat="{TemplateBinding ContentStringFormat}"
ContentTemplate="{TemplateBinding ContentTemplate}" />
<!-- JMO: Removed the focus visual altogether by setting border thickness to zero -->
<Border x:Name="FocusVisual"
BorderBrush="#FFFFC92B"
BorderThickness="0"
CornerRadius="1"
Opacity="0"
SnapsToDevicePixels="True" />
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="MouseOverVisual"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0" />
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="contentPresenter"
Storyboard.TargetProperty="Opacity"
To="0.5"
Duration="0" />
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="SelectionStates">
<VisualState x:Name="Unselected" />
<VisualState x:Name="Selected">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="SelectedVisual"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0" />
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="FocusVisual"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0" />
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
CodePudding user response:
The ContentPresenter itself receives data from the ContentControl. You have set bindings for its properties. Perhaps that's why this automatic mechanism was turned off for him.
Try to set it as it is done in the default ListBoxItem Template.
<ContentPresenter
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>