WPF. ListBox item style

LTU picture LTU · Jul 17, 2015 · Viewed 19.8k times · Source

I have problem with ListBox item style, I create two styles and do not know to use it together. 1st style is for ListBox item size, mouse over color and so on, or second is for item background (Alternation count). If I leave one of them they work fine, but how to make them work together? Or maybe I could it write in one style?

My code is:

..... <Style x:Key="Style2"
       TargetType="{x:Type ListBoxItem}">
        <Setter Property="SnapsToDevicePixels" Value="true"/>
        <Setter Property="OverridesDefaultStyle" Value="true"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBoxItem">
                    <Border 
                        Name="Border"
                        Padding="7"
                        SnapsToDevicePixels="True">
                        <ContentPresenter />
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsSelected" Value="true">
                            <Setter TargetName="Border" Property="Background"
                                    Value="{StaticResource SelectedBackgroundBrush}"/>
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Foreground"
                                    Value="{StaticResource DisabledForegroundBrush}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <Trigger Property="ItemsControl.AlternationIndex" Value="0">
                <Setter Property="Background" Value="#FFFFFF"></Setter>
            </Trigger>
            <Trigger Property="ItemsControl.AlternationIndex" Value="1">
                <Setter Property="Background" Value="#F7F7F7"></Setter>
            </Trigger>
        </Style.Triggers>
    </Style>

    <Style  x:Key="{x:Type ListBoxItem}"
        TargetType="{x:Type ListBoxItem}"
        BasedOn="{StaticResource Style2}">
        <Style.Triggers>
            <Trigger Property="ItemsControl.AlternationIndex" Value="0">
                <Setter Property="Background" Value="#19f39611"></Setter>
            </Trigger>
            <Trigger Property="ItemsControl.AlternationIndex" Value="1">
                <Setter Property="Background" Value="#19000000"></Setter>
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>


<Grid >
    <ScrollViewer Margin="30,98,362,30">
        <ListBox x:Name="lbPersonList" AlternationCount="2">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Name}"/>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </ScrollViewer>
</Grid>

Answer

Nacho picture Nacho · Jul 17, 2015

You can use BasedOn

<Style x:Key="Style1" TargetType="ListBoxItem">
    ...
</Style>

<Style x:Key="{x:Type ListBoxItem}" TargetType="ListBoxItem" BasedOn={StaticResource Style1}>
    ...
</Style>

EDITED

The problem was the Background setter of the ControlTemplate. This is the solution (using AlternationConverter instead of triggers):

<Window.Resources>
    <AlternationConverter x:Key="BackgroundConverter">
        <SolidColorBrush Color="#19f39611" />
        <SolidColorBrush Color="#19000000" />
    </AlternationConverter>

    <Style x:Key="Style2" TargetType="{x:Type ListBoxItem}">
        <Setter Property="SnapsToDevicePixels" Value="true"/>
        <Setter Property="OverridesDefaultStyle" Value="true"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBoxItem">
                    <Border Name="Border" Padding="7" SnapsToDevicePixels="True" Background="{TemplateBinding Background}">
                        <ContentPresenter />
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsSelected" Value="true">
                            <Setter TargetName="Border" Property="Background" Value="Gray"/>
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Foreground" Value="Green"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <Style x:Key="Style1" TargetType="{x:Type ListBoxItem}" BasedOn="{StaticResource Style2}">
        <Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Self},
                 Path=(ItemsControl.AlternationIndex),
                 Converter={StaticResource BackgroundConverter}}"/>
    </Style>
</Window.Resources>

<ListBox x:Name="lbPersonList" AlternationCount="2" ItemContainerStyle="{StaticResource Style1}">
...