Question



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:

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

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

Was it helpful?

Solution

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

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

<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 ContentPresenter so that the content of the items will still be shown. See the Control.Template Property page on MSDN for an example.

OTHER TIPS

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

Take a look at this link:

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>

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

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top