Search code examples
wpfxamlstylinglistboxitemstaticresource

WPF - ListBox ignores Style When ItemsSource is bound


I have created styled a ListBox in WPF so that it is rendered as a checkbox list.

When I populate the ListBox's items manually, the styling works perfectly. However, when I instead bind the ItemsSource of the ListBox to a static resource (an ItemsControl containing the required items), the styling is completely dropped.

Here's the style:

<Style x:Key="CheckBoxListStyle" TargetType="ListBox">
    <Style.Resources>
        <Style TargetType="ListBoxItem">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListBoxItem">
                        <Grid Margin="2">
                            <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto" />
                                    <ColumnDefinition />
                            </Grid.ColumnDefinitions>
                            <CheckBox IsChecked="{Binding IsSelected, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"/>
                            <ContentPresenter
                                Grid.Column="1"
                                Margin="2,0,0,0" />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Style.Resources>
    <Setter Property="ItemsPanel">
        <Setter.Value>
            <ItemsPanelTemplate>
                <WrapPanel Orientation="Vertical"  />
            </ItemsPanelTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="BorderThickness" Value="0" />
    <Setter Property="Background" Value="Transparent" />
</Style>

Here's the code for the ListBox that shows the style correctly:

<ListBox x:Name="ColumnsList"
            Grid.Column="0"
            Grid.Row="0"
            Style="{StaticResource CheckBoxListStyle}"
            BorderThickness="1">                                                
            <ListBox.Items>
                <ListBoxItem>Test</ListBoxItem>
                <ListBoxItem>Test2</ListBoxItem>
                <ListBoxItem>Test3</ListBoxItem>
            </ListBox.Items>
        </ListBox>

Here's the code for the ListBox that ignores the style:

<ListBox x:Name="ColumnsList2"
            Grid.Column="0"
            Grid.Row="0"
            Style="{StaticResource CheckBoxListStyle}"
            BorderThickness="1"
            ItemsSource="{Binding Source={StaticResource Test1}, Path=Items}">
        </ListBox>

Hoping someone can help - I'm pretty new to all this and have tried everything I can think of, but everything I've read leads me to believe that setting ItemsSource should have the same outcome as setting the items manually, so I can't see any reason why this would not work.

Thanks,

AT


Solution

  • Change the Style.Resources to setting the ItemContainerStyle property and it should work like a charm.

        <Style x:Key="CheckBoxListStyle" TargetType="ListBox">
        <Setter Property="ItemContainerStyle">
            <Setter.Value>
                <Style TargetType="ListBoxItem">
                    <Setter Property="Template">
                        <Setter.Value>
                                <ControlTemplate TargetType="ListBoxItem">
                                <Grid Margin="2">
                                    <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="Auto" />
                                            <ColumnDefinition />
                                    </Grid.ColumnDefinitions>
                                    <CheckBox IsChecked="{Binding IsSelected, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"/>
                                    <ContentPresenter
                                        Grid.Column="1"
                                        Margin="2,0,0,0" />
                                </Grid>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </Setter.Value>
        </Setter>
        <Setter Property="ItemsPanel">
            <Setter.Value>
                <ItemsPanelTemplate>
                    <WrapPanel Orientation="Vertical"  />
                </ItemsPanelTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="BorderThickness" Value="0" />
        <Setter Property="Background" Value="Transparent" />
    </Style>
    

    In older versions (before SP1), when you define Styles in Style, one of those style will be ignored. Alternatively, you can set the Resources of Style in the parent resources..

    Hope this helps!