0
votes

When I use a ItemsControl inside my ListBox control template, my ListBoxItem control template is not applied.

I have a custom ListBox control template along with a ListBoxItem control template wrapped in styles. In my main window I have a ListBox declaration with a data template.

Control templates:

<Style TargetType="ListBoxItem" BasedOn="{StaticResource Base_Control_Style}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ListBoxItem}">
                <Border x:Name="border" BorderThickness="0" 
                        BorderBrush="Transparent" Background="Transparent">
                    <ContentPresenter Content="{TemplateBinding Content}" Margin="2"/>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsSelected" Value="True">
                        <Setter TargetName="border" Property="Background" 
                                Value="{StaticResource Base_PrimaryLight}"/>
                    </Trigger>
                    <Trigger Property="IsMouseOver" Value="True" >
                        <Setter TargetName="border" Property="Background" 
                                Value="{StaticResource Base_Secondary}"/>
                    </Trigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsMouseOver" Value="True"/>
                            <Condition Property="IsSelected" Value="True"/>
                        </MultiTrigger.Conditions>
                        <MultiTrigger.Setters>
                            <Setter TargetName="border" Property="Background"
                                    Value="{StaticResource Base_SecondaryDark}"/>
                        </MultiTrigger.Setters>
                    </MultiTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
<Style TargetType="ListBox" BasedOn="{StaticResource Base_Control_Style}">
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="Background" Value="{StaticResource Base_PrimaryDark}"/>

    <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" />
    <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
    <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ListBox">
                <Border x:Name="Border" BorderThickness="{TemplateBinding BorderThickness}" 
                        BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}">
                    <ScrollViewer Margin="2">
                        <!--<StackPanel IsItemsHost="true"/>-->
                        <!--<ItemsPresenter/>-->
                        <ItemsControl ItemsSource="{TemplateBinding ItemsSource}" 
                                      ItemTemplate="{TemplateBinding ItemTemplate}"/>
                    </ScrollViewer>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Listbox declaration:

<ListBox x:Name="recipients_listbox" Margin="10" ItemsSource="{Binding Path=Recipients}" 
                 SelectedValuePath="Email"
                 SnapsToDevicePixels="True"
                 HorizontalContentAlignment="Stretch" ScrollViewer.CanContentScroll="False">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid Margin="2,4" HorizontalAlignment="Stretch" >
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="60"/>
                            <ColumnDefinition Width="Auto"/>
                            <ColumnDefinition Width="50"/>
                            <ColumnDefinition Width="Auto"/>
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="*"/>
                            <RowDefinition Height="*"/>
                            <RowDefinition Height="*"/>
                        </Grid.RowDefinitions>

                        <Grid.Resources>
                            <Style TargetType="TextBlock">
                                <Setter Property="Foreground" Value="Black"/>
                            </Style>
                        </Grid.Resources>

                        <Image Source="{Binding ImagePath}" 
                               RenderOptions.BitmapScalingMode="HighQuality" 
                               SnapsToDevicePixels="True"
                               Grid.Column="0" Grid.Row="0" Grid.RowSpan="3" 
                               Stretch="UniformToFill" Margin="0,0,10,0"/>

                        <TextBlock Text="Name:" FontWeight="Bold" 
                                   Grid.Column="1" Grid.Row="0" VerticalAlignment="Center"/>
                        <TextBlock Text="Email:" FontWeight="Bold" 
                                   Grid.Column="1" Grid.Row="1" VerticalAlignment="Center"/>
                        <TextBlock Text="Department:" FontWeight="Bold" 
                                   Grid.Column="1" Grid.Row="2" VerticalAlignment="Center"/>

                        <TextBlock VerticalAlignment="Center" Grid.Column="3" Grid.Row="0">
                                    <Run Text="{Binding FirstName}"/>
                                    <Run Text="{Binding LastName}"/>
                        </TextBlock>
                        <TextBlock Text="{Binding Email}" 
                                   VerticalAlignment="Center" Grid.Column="3" Grid.Row="1"/>
                        <TextBlock Text="{Binding Department}" 
                                   VerticalAlignment="Center" Grid.Column="3" Grid.Row="2"/>
                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

The problem is that when I use a ItemsControl inside my ListBox control template, my ListBoxItem control template is not applied (the triggers that change background colour do not activate), while my data template is.

ListBox with ItemsControl

ListBox with ItemsControl

I have attempted to use a StackPanel with isItemsHost=True, as well as a ItemsPresenter. Both of these options applied my ListBoxItem control template, but did not apply my data template.

ListBox with StackPanel or ItemsPresenter

ListBox with StackPanel or ItemsPresenter

Is there any way to apply both my ListBoxItem control template and the data template?

1
It makes no sense to have an ItemsControl in the ControlTemplate of a ListBox. There should be a StackPanel or an ItemsPresenter. See here: docs.microsoft.com/en-us/dotnet/framework/wpf/controls/…Clemens
What exactly does "did not apply my data template" mean? The ItemTemplate?Clemens
When i have an ItemsPresenter or a StackPanel instead of an ItemsControl, the ItemTemplate which I define in the 2nd code snippet isn't applied.Cirrus86

1 Answers

0
votes

The ContentPresenter in the ControlTemplate in your ListBoxItem Style does not use the ContentTemplate property, which holds the DataTemplate of the ListBox's ItemTemplate property.

Add an appropriate TemplateBinding:

<Style TargetType="ListBoxItem">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ListBoxItem">
                <Border ...>
                    <ContentPresenter Content="{TemplateBinding Content}"
                                      ContentTemplate="{TemplateBinding ContentTemplate}"
                                      Margin="2"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    ...
</Style>

Then either use an ItemsPresenter in the ListBox's ControlTemplate, or don't set the Template property at all:

<Style TargetType="ListBox">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ListBox">
                <Border BorderThickness="{TemplateBinding BorderThickness}" 
                        BorderBrush="{TemplateBinding BorderBrush}"
                        Background="{TemplateBinding Background}">
                    <ScrollViewer Margin="2">
                        <ItemsPresenter/>
                    </ScrollViewer>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    ...
</Style>