WPF. ListBox item style

22,828

Solution 1

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}">
...

Solution 2

Using Dynamic resource you can achieve this using single listboxitem style

 <Window.Resources>                              
    <Style x:Key="Lststyle" TargetType="ListBoxItem">           
        <Setter Property="SnapsToDevicePixels" Value="true"/>        
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBoxItem">
                    <Border Name="Border" Background="Transparent" Padding="7" SnapsToDevicePixels="True">                         
                        <ContentPresenter />
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="ListBox.AlternationIndex" Value="0">
                            <Setter TargetName="Border"  Property="Background" Value="{DynamicResource Color0}"/>
                        </Trigger>
                        <Trigger Property="ListBox.AlternationIndex" Value="1">
                            <Setter TargetName="Border"  Property="Background" Value="{DynamicResource Color1}"/>
                        </Trigger>
                        <Trigger Property="ListBoxItem.IsSelected" Value="true">
                            <Setter TargetName="Border" Property="Background" Value="Green"/>
                        </Trigger>
                        <Trigger Property="ListBoxItem.IsEnabled" Value="false">
                            <Setter Property="Foreground" Value="LightGray"/>
                        </Trigger>                           
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>          
    </Style>   
</Window.Resources>

<StackPanel >
    <TextBlock Text="Listbox1"></TextBlock>
    <ScrollViewer >
        <ListBox x:Name="lbPersonList" ItemContainerStyle="{StaticResource Lststyle}" AlternationCount="2"> 
            <ListBox.Resources>
                <SolidColorBrush x:Key="Color0" Color="#19f39611"></SolidColorBrush>
                <SolidColorBrush x:Key="Color1" Color="#19000000"></SolidColorBrush>
            </ListBox.Resources>
            <TextBlock Text="listboxitem1"></TextBlock>
            <TextBlock  Text="listboxitem1"></TextBlock>
            <TextBlock Text="listboxitem1"></TextBlock>
        </ListBox>
    </ScrollViewer>
    <TextBlock Margin="0,10,0,0" Text="Listbox2"></TextBlock>
    <ScrollViewer>
        <ListBox x:Name="lbPersonList1" ItemContainerStyle="{StaticResource Lststyle}" AlternationCount="2">
            <ListBox.Resources>
                <SolidColorBrush x:Key="Color0" Color="Yellow"></SolidColorBrush>
                <SolidColorBrush x:Key="Color1" Color="Blue"></SolidColorBrush>
            </ListBox.Resources>
            <TextBlock Text="listboxitem1"></TextBlock>
            <TextBlock Text="listboxitem1"></TextBlock>
            <TextBlock Text="listboxitem1"></TextBlock>
        </ListBox>
    </ScrollViewer>
</StackPanel>

Simplified xaml

<Window.Resources>
    <Style x:Key="lst1" TargetType="ListBox" >
        <Style.Resources>
            <SolidColorBrush x:Key="Color0" Color="#19f39611"></SolidColorBrush>
            <SolidColorBrush x:Key="Color1" Color="#19000000"></SolidColorBrush>
        </Style.Resources>
    </Style>
    <Style x:Key="lst2" TargetType="ListBox" >
        <Style.Resources>
            <SolidColorBrush x:Key="Color0" Color="Blue"></SolidColorBrush>
            <SolidColorBrush x:Key="Color1" Color="Yellow"></SolidColorBrush>
        </Style.Resources>
    </Style>
    <Style x:Key="Lststyle" TargetType="ListBoxItem">
        <Setter Property="SnapsToDevicePixels" Value="true"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ListBoxItem">
                    <Border Name="Border" Background="Transparent" Padding="7" SnapsToDevicePixels="True">
                        <Border.Style>
                            <Style TargetType="Border">
                                <Style.Triggers>
                                    <Trigger Property="ItemsControl.AlternationIndex" Value="0">
                                        <Setter  Property="Background" Value="{DynamicResource Color0}"/>
                                    </Trigger>
                                    <Trigger Property="ItemsControl.AlternationIndex" Value="1">
                                        <Setter  Property="Background" Value="{DynamicResource Color1}"/>
                                    </Trigger>
                                </Style.Triggers>
                            </Style>
                        </Border.Style>
                        <ContentPresenter />
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="ListBox.AlternationIndex" Value="0">
                            <Setter TargetName="Border"  Property="Background" Value="{DynamicResource Color0}"/>
                        </Trigger>
                        <Trigger Property="ListBox.AlternationIndex" Value="1">
                            <Setter TargetName="Border"  Property="Background" Value="{DynamicResource Color1}"/>
                        </Trigger>
                        <Trigger Property="ListBoxItem.IsSelected" Value="true">
                            <Setter TargetName="Border" Property="Background" Value="Green"/>
                        </Trigger>
                        <Trigger Property="ListBoxItem.IsEnabled" Value="false">
                            <Setter Property="Foreground" Value="LightGray"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

</Window.Resources>
<StackPanel >
    <TextBlock Text="Listbox1"></TextBlock>
    <ScrollViewer >
        <ListBox x:Name="lbPersonList" Style="{StaticResource lst1}" ItemContainerStyle="{StaticResource Lststyle}" AlternationCount="2">![enter image description here][2]              
            <TextBlock Text="listboxitem1"></TextBlock>
            <TextBlock  Text="listboxitem1"></TextBlock>
            <TextBlock Text="listboxitem1"></TextBlock>
        </ListBox>
    </ScrollViewer>
    <TextBlock Margin="0,10,0,0" Text="Listbox2"></TextBlock>
    <ScrollViewer>
        <ListBox x:Name="lbPersonList1" Style="{StaticResource lst2}" ItemContainerStyle="{StaticResource Lststyle}" AlternationCount="2">               
            <TextBlock Text="listboxitem1"></TextBlock>
            <TextBlock Text="listboxitem1"></TextBlock>
            <TextBlock Text="listboxitem1"></TextBlock>
        </ListBox>
    </ScrollViewer>
</StackPanel>

enter image description here

Share:
22,828
LTU
Author by

LTU

Updated on July 09, 2022

Comments

  • LTU
    LTU almost 2 years

    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>