WPF. Стиль элемента ListBox

У меня проблема со стилем элемента ListBox, я создаю два стиля и не знаю, как использовать их вместе. 1-й стиль предназначен для размера элемента ListBox, цвета указателя мыши и т. д., а второй — для фона элемента (количество чередований). Если я оставлю один из них, они будут работать нормально, но как заставить их работать вместе? Или, может быть, я мог бы написать в одном стиле?

Мой код:

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


person LTU    schedule 17.07.2015    source источник


Ответы (3)


Вы можете использовать На основе

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

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

ОТРЕДАКТИРОВАНО

Проблема была в установщике фона ControlTemplate. Это решение (с использованием AlternationConverter вместо триггеров):

<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}">
...
person Nacho    schedule 17.07.2015
comment
если я использую ваш пример, как я могу вызвать этот стиль в опции ListBox? Потому что знаю, что работает только style1 (Alternationcount не работает) - person LTU; 17.07.2015
comment
Проблема была в установщике фона ControlTemplate. Я отредактировал свой ответ. - person Nacho; 17.07.2015

Используя Динамический ресурс, вы можете добиться этого, используя один элемент списка стиль

 <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>

Упрощенный 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>

введите здесь описание изображения

person Heena Patil    schedule 17.07.2015

Вы должны установить для каждого стиля правильный x:Key, а затем для одного из ваших стилей вы можете использовать BasedOn={StaticResource Style1}, который добавляется к вашему текущему стилю, style1. (Проверьте документацию: https://msdn.microsoft.com/en-us/library/system.windows.style.basedon(v=vs.110).aspx)

Проверьте это:

    <Style x:Key="Style2"
           TargetType="ListBoxItem">
        <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>
        <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 Property="Background"
                                    Value="Red" />
                        </Trigger>
                        <Trigger Property="IsEnabled"
                                 Value="false">
                            <Setter Property="Foreground"
                                    Value="Gray" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <Style  TargetType="{x:Type ListBoxItem}"
            BasedOn="{StaticResource Style2}">
        <Setter Property="SnapsToDevicePixels"
                Value="true" />
        <Style.Triggers>

            <Trigger Property="ListBox.AlternationIndex"
                     Value="0">
                <Setter Property="Background"
                        Value="CornflowerBlue" />
                <Setter Property="Foreground"
                        Value="Black" />
            </Trigger>

            <Trigger Property="ItemsControl.AlternationIndex"
                     Value="1">
                <Setter Property="Background"
                        Value="LightBlue" />
                <Setter Property="Foreground"
                        Value="Red" />
            </Trigger>
        </Style.Triggers>
    </Style>
person Shmwel    schedule 17.07.2015
comment
Хорошо, исправляю, а как мне написать это в опции ListBox (см. в ‹Сетке›.....)? Потому что теперь работает только первый стиль (счет чередования не работает) - person LTU; 17.07.2015
comment
Проверьте новое обновление.:D Ну, вы должны знать, что при использовании BasedOn новый стиль перезапишет все уже определенные стили. Например, Alternation не будет работать одновременно. Будет принят во внимание только один из них, потому что этот триггер определен в обоих стилях. - person Shmwel; 17.07.2015
comment
Как я могу заставить их работать вместе? Может быть, его возможные свойства счетчика чередования помещены в первый стиль? - person LTU; 17.07.2015
comment
Ну... я не очень понимаю, как вы хотите их объединить. Есть ли свойство, от которого оно зависит? По крайней мере, есть либо (например, синий и красный), либо что-то еще.. Можете ли вы подробно объяснить сценарий? Итак, как я уже сказал, вы не можете комбинировать, если это определено в обоих стилях. Для Чередования одновременно должен применяться 1 триггер (не может быть два, три и т. д.). - person Shmwel; 17.07.2015
comment
Может быть, вы знаете, как сделать Чередование без триггеров? - person LTU; 17.07.2015
comment
Проверьте новое обновление. Ну.. это довольно странно. Вы не должны использовать оба стиля, которые делают одно и то же. Проблема, которую вы должны иметь, заключается в том, что существует 2 разных стиля, которые пытаются изменить цвет фона ListBoxItem, что приведет к тому, что поток не будет воспроизводиться так, как вы хотите. - person Shmwel; 17.07.2015