Home > Back-end >  ItemContainerStyle disables ItemTemplateSelector for ListBox. Why?
ItemContainerStyle disables ItemTemplateSelector for ListBox. Why?

Time:11-04

In my WPF app (.NET 6.0) I have an ItemContainerStyle for a ListBoxItem that I've used successfully on ListBoxes 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 ListBoxItems 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}"/>
  • Related