繁体   English   中英

WPF选择具有自定义边框的ListBoxItem

[英]WPF Selected ListBoxItem with custom border



我正在尝试创建一个ListBoxItem模板,该模板在选择时将带有圆形边框。 我得到了这个xaml,在选择时不起作用:

<ListBox x:Name="filtersListBox" Grid.Row="1" 
         Background="Transparent" BorderThickness="0"
         ItemsSource="{Binding FilterItems}">
    <ListBox.ItemContainerStyle>
        <Style TargetType="{x:Type ListBoxItem}">
            <Style.Resources>
                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent"/>
                <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent"/>
            </Style.Resources>
        </Style>
    </ListBox.ItemContainerStyle>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid HorizontalAlignment="Center">
                <Border CornerRadius="8" BorderThickness="0" BorderBrush="Orange" 
                        Margin="2" Background="Transparent" Name="itemBorder"
                        Width="275" VerticalAlignment="Center"
                        FocusManager.IsFocusScope="True" Focusable="True">
                    <Border.Effect>
                        <DropShadowEffect BlurRadius="1" ShadowDepth="2" Color="DarkOrange" Opacity="0.3"/>
                    </Border.Effect>
                    <Border.Style>
                        <Style TargetType="Border">
                            <Style.Triggers>
                                <Trigger Property="UIElement.IsFocused" Value="True">
                                    <Setter Property="Background" Value="Blue"/>
                                </Trigger>
                                <EventTrigger RoutedEvent="Border.MouseEnter">
                                    <BeginStoryboard>
                                        <Storyboard>
                                            <ThicknessAnimation Duration="0:0:0.25"
                                                                To="2"
                                                                Storyboard.TargetProperty="BorderThickness"/>
                                        </Storyboard>
                                    </BeginStoryboard>
                                </EventTrigger>
                                <EventTrigger RoutedEvent="Border.MouseLeave">
                                    <BeginStoryboard>
                                        <Storyboard>
                                            <ThicknessAnimation Duration="0:0:0.25"
                                                                To="0"
                                                                Storyboard.TargetProperty="BorderThickness"/>
                                        </Storyboard>
                                    </BeginStoryboard>
                                </EventTrigger>
                            </Style.Triggers>
                        </Style>
                    </Border.Style>
                    <TextBlock Text="{Binding Text}" Margin="10, 2"/>
                </Border>
            </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

这就是我正在处理的ListBox。
MouseEnter和MouseLeave事件非常有效!
但是,UIElement.IsFocused的触发器不起作用。

任何建议将不胜感激! :)
谢谢,亚历克斯。

这很容易做到,我很惊讶没有人提出这个建议。 定义两个DataTemplate或两个ControlTemplate ,一个用于默认外观,一个用于所选外观。 然后只需添加以下Style (第一个示例使用DataTemplate ):

<Style x:Key="SelectionStyle" TargetType="{x:Type ListBoxItem}">
    <Setter Property="ContentTemplate" Value="{StaticResource DefaultTemplate}" />
    <Style.Triggers>
        <Trigger Property="IsSelected" Value="True">
            <Setter Property="ContentTemplate" Value="{StaticResource SelectedTemplate}" />
        </Trigger>
    </Style.Triggers>
</Style>

您可以这样使用它:

<ListBox ItemContainerStyle="{StaticResource SelectionStyle}" ... />

这是另一个使用两个ControlTemplate的示例(以相同的方式使用):

<Style x:Key="SelectionStyle" TargetType="{x:Type ListBoxItem}">
    <Setter Property="Template" value="{StaticResource DefaultTemplate}" />
    <Style.Triggers>
        <Trigger Property="IsSelected" Value="True">
            <Setter Property="Template" value="{StaticResource SelectedTemplate}" />
        </Trigger>
    </Style.Triggers>
</Style>

我将让您定义所需的东西,如您所知。 最后一点...如果使用此方法(使用ControlTemplate ),请确保添加ContentPresenter以便仍显示项目的内容。 有关示例,请参见MSDN上的Control.Template属性页。

您是否尝试过将Focusable属性设置为true。 默认情况下,属性为false。

看一下这个链接:

http://msdn.microsoft.com/en-us/library/system.windows.uielement.focusable%28v=vs.110%29.aspx

如果那没有帮助,那么也许这种方法会更适合您。

<ListBox.Resources>
    <Style TargetType="{x:Type ListBoxItem}">
        <EventSetter Event="GotFocus" Handler="ListBoxItem_GotFocus"/>
        <EventSetter Event="LostFocus" Handler="ListBoxItem_LostFocus"/>
    </Style>
</ListBox.Resources>

为什么不为ItemContainerStyle设置模板,那么可以将触发器与属性IsSelected = true一起使用。 参见下面的代码:

<Window x:Class="WpfApplication7.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:system="clr-namespace:System;assembly=mscorlib"
    xmlns:collections="clr-namespace:System.Collections;assembly=mscorlib"
    Title="MainWindow" Height="350" Width="525">
<Window.Resources>
    <collections:ArrayList  x:Key="StringArray">
        <system:String>Hei</system:String>
        <system:String>Hei</system:String>
        <system:String>Hei</system:String>
        <system:String>Hei</system:String>
    </collections:ArrayList>
</Window.Resources>
<Grid>
    <ListBox x:Name="filtersListBox" Grid.Row="1" 
     Background="Transparent" BorderThickness="0"
     ItemsSource="{StaticResource StringArray}">
        <ListBox.ItemContainerStyle>
            <Style TargetType="{x:Type ListBoxItem}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ListBoxItem">
                            <Border CornerRadius="8" BorderThickness="0" BorderBrush="Orange" 
                    Margin="2" Background="Transparent" Name="itemBorder"
                    Width="275" VerticalAlignment="Center"
                    FocusManager.IsFocusScope="True" Focusable="True">
                                <Border.Effect>
                                    <DropShadowEffect BlurRadius="1" ShadowDepth="2" Color="DarkOrange" Opacity="0.3"/>
                                </Border.Effect>
                                <ContentPresenter />
                            </Border>
                                    <ControlTemplate.Triggers>
                                        <Trigger Property="IsSelected" Value="True">
                                            <Setter TargetName="itemBorder" Property="Background" Value="Blue"></Setter>
                                        </Trigger>
                                    </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
                <Style.Resources>
                    <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent"/>
                    <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent"/>
                </Style.Resources>
            </Style>
        </ListBox.ItemContainerStyle>
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Grid HorizontalAlignment="Center">
                    <Border CornerRadius="8" BorderThickness="0" BorderBrush="Orange" 
                    Margin="2" Background="Transparent" Name="itemBorder"
                    Width="275" VerticalAlignment="Center"
                    FocusManager.IsFocusScope="True" Focusable="True">
                        <Border.Effect>
                            <DropShadowEffect BlurRadius="1" ShadowDepth="2" Color="DarkOrange" Opacity="0.3"/>
                        </Border.Effect>
                        <Border.Style>
                            <Style TargetType="Border">
                                <Style.Triggers>
                                    <Trigger Property="UIElement.IsFocused" Value="True">
                                        <Setter Property="Background" Value="Blue"/>
                                    </Trigger>
                                    <EventTrigger RoutedEvent="Border.MouseEnter">
                                        <BeginStoryboard>
                                            <Storyboard>
                                                <ThicknessAnimation Duration="0:0:0.25"
                                                            To="2"
                                                            Storyboard.TargetProperty="BorderThickness"/>
                                            </Storyboard>
                                        </BeginStoryboard>
                                    </EventTrigger>
                                    <EventTrigger RoutedEvent="Border.MouseLeave">
                                        <BeginStoryboard>
                                            <Storyboard>
                                                <ThicknessAnimation Duration="0:0:0.25"
                                                            To="0"
                                                            Storyboard.TargetProperty="BorderThickness"/>
                                            </Storyboard>
                                        </BeginStoryboard>
                                    </EventTrigger>
                                </Style.Triggers>
                            </Style>
                        </Border.Style>
                        <TextBlock Text="{Binding }" Margin="10, 2"/>
                    </Border>
                </Grid>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM