Стиль SelectedItem не работает для ListBox с DataTemplate? - PullRequest
0 голосов
/ 07 ноября 2019

У меня есть ListBox с DataTemplate, и мне нужно изменить цвет фона выбранного элемента. Я нашел какой-то пример и попробовал все из них, но, вероятно, пропустил какой-то пункт.

Я попытался изменить ресурс SolidColorBrush и добавить триггер для IsSelected в ListBox Style и дляListBoxItem Style, но ничего из этого не работает.

<Window.Resources>
    <Style x:Key="ListBoxGreenStyle" TargetType="{x:Type ListBox}">
        <Style.Resources>
            <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="LightGreen" />
            <SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="LightGreen" />
        </Style.Resources>
        <Style.Triggers>
            <Trigger Property="IsSelected" Value="True">
                <Setter Property="Background" Value="LightGreen" />
            </Trigger>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="Background" Value="LightBlue" />
            </Trigger>
        </Style.Triggers>
    </Style>

    <Style x:Key="ListBoxDragDrop" TargetType="{x:Type ListBoxItem}">
        <Setter Property="AllowDrop" Value="true"/>
        <EventSetter Event="PreviewMouseMove" Handler="ListBox_PreviewMouseMove"/>
        <EventSetter Event="PreviewMouseLeftButtonDown" Handler="ListBox_PreviewMouseLeftButtonDown"/>
        <EventSetter Event="Drop" Handler="ListBox_Drop"/>
        <Style.Resources>
            <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="LightGreen" />
            <SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="LightGreen" />
        </Style.Resources>
        <Style.Triggers>
            <Trigger Property="IsSelected" Value="True">
                <Setter Property="Background" Value="LightGreen" />
            </Trigger>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="Background" Value="LightBlue" />
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>

<ListBox x:Name="lstSlides" Grid.Row="1" Grid.Column="0" Grid.RowSpan="1" Margin="5" Drop="lstSlides_Drop" DragEnter="lstSlides_DragEnter" AllowDrop="True" ItemContainerStyle="{DynamicResource ListBoxDragDrop}" SelectionMode="Extended" SelectionChanged="lstSlides_SelectionChanged" Style="{DynamicResource ListBoxGreenStyle}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="40"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <Image Grid.Column="0" Source="{Binding Image}" Height="32" Width="32" HorizontalAlignment="Center" VerticalAlignment="Center"/>
                <Label Grid.Column="1" Content="{Binding ItemCount}" HorizontalAlignment="Center"/>
                <Label Grid.Column="2" Content="{Binding Name}"/>
            </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Как правильно Style, куда добавить триггеры или изменить ресурс SolidColorBrush?

Ответы [ 2 ]

0 голосов
/ 07 ноября 2019

Вы должны изменить свой стиль «ListBoxDragDrop», добавив по умолчанию ItemContainerStyle. Затем вы можете изменить SolidColorBrush, как вам нравится.

<Style x:Key="FocusVisual">
    <Setter Property="Control.Template">
        <Setter.Value>
            <ControlTemplate>
                <Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
<SolidColorBrush x:Key="Item.MouseOver.Background" Color="#1F26A0DA"/>
<SolidColorBrush x:Key="Item.MouseOver.Border" Color="#a826A0Da"/>
<SolidColorBrush x:Key="Item.SelectedInactive.Background" Color="LightGreen"/>
<SolidColorBrush x:Key="Item.SelectedInactive.Border" Color="Green"/>
<SolidColorBrush x:Key="Item.SelectedActive.Background" Color="LightGreen"/>
<SolidColorBrush x:Key="Item.SelectedActive.Border" Color="Green"/>

<Style x:Key="ListBoxDragDrop" TargetType="{x:Type ListBoxItem}">
    <Setter Property="AllowDrop" Value="true"/>
    <EventSetter Event="PreviewMouseMove" Handler="ListBox_PreviewMouseMove"/>
    <EventSetter Event="PreviewMouseLeftButtonDown" Handler="ListBox_PreviewMouseLeftButtonDown"/>
    <EventSetter Event="Drop" Handler="ListBox_Drop"/>

    <Setter Property="SnapsToDevicePixels" Value="True"/>
    <Setter Property="Padding" Value="4,1"/>
    <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
    <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="BorderBrush" Value="Transparent"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ListBoxItem}">
                <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
                    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                </Border>
                <ControlTemplate.Triggers>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsMouseOver" Value="True"/>
                        </MultiTrigger.Conditions>
                        <Setter Property="Background" TargetName="Bd" Value="{StaticResource Item.MouseOver.Background}"/>
                    </MultiTrigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="Selector.IsSelectionActive" Value="False"/>
                            <Condition Property="IsSelected" Value="True"/>
                        </MultiTrigger.Conditions>
                        <Setter Property="Background" TargetName="Bd" Value="{StaticResource Item.SelectedInactive.Background}"/>
                        <Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource Item.SelectedInactive.Border}"/>
                    </MultiTrigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="Selector.IsSelectionActive" Value="True"/>
                            <Condition Property="IsSelected" Value="True"/>
                        </MultiTrigger.Conditions>
                        <Setter Property="Background" TargetName="Bd" Value="{StaticResource Item.SelectedActive.Background}"/>
                        <Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource Item.SelectedActive.Border}"/>
                    </MultiTrigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsMouseOver" Value="True"/>
                        </MultiTrigger.Conditions>
                        <Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource Item.MouseOver.Border}"/>
                    </MultiTrigger>
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter Property="TextElement.Foreground" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
0 голосов
/ 07 ноября 2019

Самый простой способ - избавиться от Style, который вы объявляете для вашего ListBoxItem, и использовать вместо него DataTrigger в DataTemplate, который вы используете внутри ListBox:

<DataTemplate.Triggers>
    <DataTrigger Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBoxItem}}" Value="True">
        <Setter TargetName="grid" Property="Background" Value="Red"></Setter>
    </DataTrigger>
</DataTemplate.Triggers>

(Не забудьте добавить x:Name="grid" к вашему Grid.)

Привязка RelativeSource позволяет WPF искать визуальное дерево, пока не найдет ListBoxItem (и это произойдет, потому что выявляются шаблонами Content каждого ListBoxItem).

Это установит свойство Background содержимого ListBoxItem в Red. Он не изменит свойства Background самого ListBoxItem!

Если это то, что вам нужно, более сложный, но самый мощный вариант - полностью перезаписать свойство Template ListBoxItem, используяa Style:

<Style x:Key="{x:Type ListBoxItem}" TargetType="ListBoxItem">
    <Setter Property="SnapsToDevicePixels" Value="true" />
    <Setter Property="OverridesDefaultStyle" Value="true" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ListBoxItem">
                <Border x:Name="Border" Padding="2" SnapsToDevicePixels="true">
                    <Border.Background>
                        <SolidColorBrush Color="Transparent" />
                    </Border.Background>
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="SelectionStates">
                            <VisualState x:Name="Unselected" />
                            <VisualState x:Name="Selected">
                                <Storyboard>
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
                                        <EasingColorKeyFrame KeyTime="0" Value="Red" />
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="SelectedUnfocused">
                                <Storyboard>
                                    <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
                                        <EasingColorKeyFrame KeyTime="0" Value="Green" />
                                    </ColorAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <ContentPresenter />
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Таким образом, вы можете переопределить каждое свойство во всех состояниях (Selected, Unselected, Focused и т. д.). Это только отправная точка, вдохновленная этой страницей MSDN .

К сожалению, невозможно переопределить только часть ControlTemplate. Если вы переписываете его, вам нужно переписать каждую его часть, даже те части, которые вы не хотите менять.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...