Change ListViewItem background colour on mouse over
Asked Answered
P

4

14

I need some help here. I can't understand why none of the solutions I found work for my case. Let's consider a Listview with these items:

<ListView.Items>
    <ListViewItem>
          <TextBlock xml:space="preserve">  1 <Bold>I'm bold</Bold>   </TextBlock>
    </ListViewItem>
    <ListViewItem>
          <TextBlock  xml:space="preserve"> 2 Im not </TextBlock>
    </ListViewItem>
</ListView.Items>

Initially on hover each row I saw the highlight of the TextBlock in its default light blue. It only underlined the area with text:

I don't want that highlight I want the one of the whole row, and I want to decide the colour. I also want the highlight of the whole row when selecting: enter image description here

I've been playing with Styles, Triggers or the ItemContainerStyle. I realized that I have to consider the background of the Textbox, and the one of the ListViewItem for the area with text. And the background of the whole row seems to be a business of the ListView.ItemContainerStyle.

The result of adding a style fot the TextBox:

    <Style x:Key="TextBlockStyle" TargetType="{x:Type TextBlock}">
        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
               <Setter Property="Foreground" Value="Black" />
                <Setter Property="Background" Value="White"/> 
            </Trigger>
        </Style.Triggers>
    </Style>

<ListView Grid.Column="1" Margin="0" HorizontalContentAlignment="Stretch" BorderThickness="0" >
        <ListView.Resources>
                <Style BasedOn="{StaticResource TextBlockStyle}" TargetType="{x:Type TextBlock}" />   
          </ListView.Resources>

is: enter image description here

Then I add another style to try to get rid of the ListView background under the TextBox:

    <Style x:Key="ListViewItemStyle" TargetType="{x:Type ListViewItem}">
                    <Style.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Background" Value="Gold" />
                        </Trigger>
                    </Style.Triggers>
     </Style>

 <ListView Grid.Column="1" Margin="0" HorizontalContentAlignment="Stretch" BorderThickness="0" >
        <ListView.Resources>
                <Style BasedOn="{StaticResource TextBlockStyle}" TargetType="{x:Type TextBlock}" />
                 <Style BasedOn="{StaticResource ListViewItemStyle}" TargetType="{x:Type ListViewItem}" />    
          </ListView.Resources>

But this has no effect at all.

And trying to highlight the whole row with this doesn't work:

<ItemsControl.ItemContainerStyle>
    <Style>
        <Style.Triggers>
               <Trigger Property="Control.IsMouseOver" Value="True">
                    <Setter Property="Control.Background" Value="Gold" />
                        </Trigger>
         </Style.Triggers>
    </Style>
</ItemsControl.ItemContainerStyle>

And tried several other suggestions for hours. This one: Remove the mouse over effect on a ListView in WPF avoids the highlight over the text on hover,both for the TextBox and the ListViewItem, but I don't know how to change then the background of the whole row. Could someone provide an example of what I'm trying to do?

Pegu answered 1/7, 2016 at 19:41 Comment(1)
Change the background of the Container in your DataTemplate.Lippert
B
29

The easiest way to see and change all styling-options for a given element is to export the default template for a control.

Therefore open Visual Studio or Blend and Right Click in the Design View on a control. Hover to 'Edit Template' -> And select 'Edit a Copy...' Output:

        <SolidColorBrush x:Key="Item.MouseOver.Background" Color="Gold"/>
        <SolidColorBrush x:Key="Item.MouseOver.Border" Color="#a826A0Da"/>
        <SolidColorBrush x:Key="Item.SelectedInactive.Background" Color="#3DDADADA"/>
        <SolidColorBrush x:Key="Item.SelectedInactive.Border" Color="#FFDADADA"/>
        <SolidColorBrush x:Key="Item.SelectedActive.Background" Color="#3D26A0DA"/>
        <SolidColorBrush x:Key="Item.SelectedActive.Border" Color="#FF26A0DA"/>

        <Style x:Key="ListViewContainerStyle" TargetType="{x:Type ListViewItem}">
            <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 ListViewItem}">
                        <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}"/>
                                <Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource Item.MouseOver.Border}"/>
                            </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>
                            <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>

Now you have a good starting point to get your ItemContainerStyle customized.

Brut answered 2/7, 2016 at 8:56 Comment(1)
This code follows the idea of the solution in the link I provided. Here the result is the same than the initial situation but with a customized colour. It would solve my problem if I could change the ListViewItem width to be the same as the whole row. But if I change the HorizontalContentAlignment property to take the value Stretch, instead of the provided in your code, it doesn't work.Architectural
Q
21

Try this:

        <ListView.ItemContainerStyle>
            <Style TargetType="{x:Type ListViewItem}">
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="Gold" />
                    </Trigger>
                </Style.Triggers>
            </Style>
        </ListView.ItemContainerStyle>
Quaint answered 1/7, 2016 at 20:59 Comment(4)
I tried this but this only underlined the area with text, not the whole row.Architectural
` TargetType="{x:Type ListViewItem}"` is important in this case.Quaint
that method is not working, see @mathayk post above. list view is far more complex control and changing Background just do nothing.Canonicity
that has worked for me however i wan't to get rid of the gradient thing not sure how, if i just set the background color it changes the color but he gradient thing remainsGarget
J
1

Below is a style that allows you to change ListViewItem background colour on mouse over.

The easiest way to view and edit all styling-options for a given control is to export the default template for a control. Click on a control, Properties, Miscellaneous, ItemContainerStyle, down arrow, Convert to New Resource. It is quite a long template so I just delete the parts I didn't need.

WARNING there are two very similar items in the properties list (ItemContainerStyle and ItemContainerStyleSelector), pick the right one. It is easy to miss if the properties window is not wide enough.

    <Window.Resources>
        <Style x:Key="MIN_ListViewContainerStyle" TargetType="{x:Type ListViewItem}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBoxItem}">
                        <Border x:Name="Bd" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
                            <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Background" TargetName="Bd" Value="Gold"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    
     <StackPanel>
        <ListView ItemContainerStyle="{DynamicResource MIN_ListViewContainerStyle}">
            <ListView.Items>
                <ListViewItem>
                    <TextBlock xml:space="preserve">  1 <Bold>I'm bold</Bold></TextBlock>
                </ListViewItem>
                <ListViewItem>
                    <TextBlock  xml:space="preserve"> 2 Im not</TextBlock>
                </ListViewItem>
            </ListView.Items>
        </ListView>
    </StackPanel>
</Window>
Jiggerypokery answered 7/12, 2022 at 12:24 Comment(0)
P
0

You can refer to the code used in my project(DataGrid), I think the same goes for ListView:

enter image description here

<Style TargetType="{x:Type DataGridCell}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type DataGridCell}">
                <Grid Background="{TemplateBinding Background}">
                    <ContentPresenter Margin="0,0,8,0" VerticalAlignment="Center" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="ToolTip" Value="点击查看详情" />
    <Setter Property="ToolTipService.InitialShowDelay" Value="3000" />
    <EventSetter Event="PreviewMouseLeftButtonDown" Handler="DataGrid_Cell_PreviewMouseLeftButtonDown" />
    <Style.Triggers>
        <Trigger Property="IsSelected" Value="True">
            <Setter Property="Background" Value="#AECBFA" />
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
        </Trigger>
    </Style.Triggers>
</Style>
<Style TargetType="{x:Type DataGridRow}">
    <Setter Property="Background" Value="White" />
    <Style.Triggers>
        <DataTrigger Binding="{Binding ItemType}" Value="Ok">
            <Setter Property="Background" Value="{StaticResource OkBrush}" />
        </DataTrigger>
        <DataTrigger Binding="{Binding ItemType}" Value="Error">
            <Setter Property="Background" Value="{StaticResource ErrorBrush}" />
        </DataTrigger>
        <MultiDataTrigger>
            <MultiDataTrigger.Conditions>
                <Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="False" />
                <Condition Binding="{Binding AnalyzeStatus}" Value="Analyzing" />
            </MultiDataTrigger.Conditions>
            <MultiDataTrigger.EnterActions>
                <BeginStoryboard x:Name="bsbTwinkle">
                    <Storyboard>
                        <ColorAnimation AutoReverse="True"
                                        RepeatBehavior="Forever"
                                        Storyboard.TargetProperty="(DataGridRow.Background).(SolidColorBrush.Color)"
                                        From="Transparent"
                                        To="LightPink"
                                        Duration="0:0:1">
                            <ColorAnimation.EasingFunction>
                                <SineEase />
                            </ColorAnimation.EasingFunction>
                        </ColorAnimation>
                    </Storyboard>
                </BeginStoryboard>
            </MultiDataTrigger.EnterActions>
            <MultiDataTrigger.ExitActions>
                <RemoveStoryboard BeginStoryboardName="bsbTwinkle" />
            </MultiDataTrigger.ExitActions>
        </MultiDataTrigger>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter Property="Background" Value="#7FB5C8F9" />
        </Trigger>
    </Style.Triggers>
</Style>
Protean answered 26/9, 2021 at 4:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.