Question

I have a ListBox...

<ListBox Margin="10" ItemsSource="{Binding Employees}" 
         ItemTemplate="{DynamicResource EmployeesTemplate}"
         HorizontalContentAlignment="Stretch" BorderThickness="0" 
         ScrollViewer.CanContentScroll="False"/>

...that has a custom DataTemplate:

<Window.Resources>
    <DataTemplate x:Key="EmployeesTemplate">
        <Border BorderThickness="1" BorderBrush="Black" SnapsToDevicePixels="True"
                DockPanel.Dock="Top" Margin="0,0,0,5" Padding="5">
            <StackPanel>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="150"/>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>
                    <StackPanel Grid.Column="0" Orientation="Horizontal">
                        <TextBlock Text="{Binding Path=FirstName}" Padding="0,0,5,0"/>
                        <TextBlock Text="{Binding Path=LastName}"/>
                    </StackPanel>
                    <TextBlock Grid.Column="1" Text="{Binding Path=Title}"/>
                </Grid>
                <StackPanel>
                    <TextBlock Text="{Binding Path=DateOfBirth, StringFormat={}{0:MM/dd/yyyy}}"/>
                    <TextBlock Text="{Binding Path=Address}"/>
                    <TextBlock Text="{Binding Path=PhoneNumber}"/>
                    <TextBlock Text="{Binding Path=Salary, StringFormat={}{0:C}}"/>
                </StackPanel>
            </StackPanel>
        </Border>
    </DataTemplate>
</Window.Resources>

When I select an item from the ListBox, the selection highlighting includes the 5-point Margin that is assigned to the bottom of each item (Border in DataTemplate):

enter image description here

You'll notice the similar situation on the left side, where the highlight overflows just a little bit. I did not notice that until now... hmm. So, I would like to restrict the selection highlight to the border area and nothing outside of it and be able to retain the margin spacing between the items.

How would I accomplish that? I tried manipulating Padding and Margin as much as I could, but I could not figure it out. Maybe I have to create a custom ListBox template?

Was it helpful?

Solution

I'm not sure if there is a simpler way but it works for me. I added a DataTemplate.Triggers section to my DataTemplate...

<DataTemplate.Triggers>
    <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, 
                         AncestorType={x:Type ListBoxItem}}, Path=IsMouseOver}" Value="True">
        <Setter Property="Background" Value="LightBlue" TargetName="EmployeesTemplateBorder"/>
    </DataTrigger>

    <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, 
                         AncestorType={x:Type ListBoxItem}}, Path=IsSelected}" Value="True">
        <Setter Property="Background" Value="RoyalBlue" TargetName="EmployeesTemplateBorder"/>
    </DataTrigger>
</DataTemplate.Triggers>

...and a ListBox.Resrouces section to the ListBox (to get rid of the default highlight behavior):

<ListBox.Resources>
    <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent" />
    <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black" />
    <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent" />
</ListBox.Resources>

Obviously, that doesn't do anything to the foreground, but that's not the concern right now, since that one is relatively easy comparing to this highlight routine.

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