WPF Selected ListBoxItem 带有自定义边框

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20117675/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 10:05:31  来源:igfitidea点击:

WPF Selected ListBoxItem with custom border

c#wpfxamllistboxitemtemplate

提问by Old Account



I'm trying to create a ListBoxItem template, that will be with rounded border at selection. I got this xaml, which doesn't work on selection:



我正在尝试创建一个 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>

So this is the ListBox that I'm working on.
The MouseEnter and MouseLeave events, work great!
However, the trigger of UIElement.IsFocused is not working.

这就是我正在研究的 ListBox。
MouseEnter 和 MouseLeave 事件,效果很好!
但是,UIElement.IsFocused 的触发器不起作用。

Any advice would be very appreciated! :)
Thanks, Alex.

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

采纳答案by Sheridan

This is so easy to do, I'm quite surprised that nobody suggested this yet. Either define two DataTemplates or two ControlTemplates, one for the default look and one for the selected look. Then just add this Style(this first example uses DataTemplates):

这很容易做到,我很惊讶还没有人建议这样做。定义两个DataTemplates 或两个ControlTemplates,一个用于默认外观,一个用于选定外观。然后只需添加这个Style(第一个示例使用DataTemplates):

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

You would use it like this:

你会像这样使用它:

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

Here is the other example using two ControlTemplates (used in the same way):

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

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

I'll leave you to define what you want the items to look like as you know that best. One last note... if you use this method (using ControlTemplates), make sure that you add a ContentPresenterso that the content of the items will still be shown. See the Control.Template Propertypage on MSDN for an example.

我会让您自行定义您希望这些项目的外观,因为您最了解这一点。最后一个注意事项...如果您使用此方法(使用ControlTemplates),请确保添加 aContentPresenter以便仍会显示项目的内容。有关示例,请参阅MSDN 上的Control.Template 属性页。

回答by dev hedgehog

Have you tried setting Focusable property to true. By default the propery is false.

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

Take a look at this link:

看看这个链接:

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

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

If that doesnt help then maybe this approach will fit you more.

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

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

回答by Espen Medb?

Why dont you set the Template for ItemContainerStyle, then you can use the Trigger with property IsSelected = true. See code below:

为什么不为 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>