WPF ListView turn off selection
Asked Answered
U

15

138

Is it possible to turn off the selection of a WPF ListView, so when user clicks row, the row is not highlighted?

ListView
(source: konim5am at artax.karlin.mff.cuni.cz)

I would like the row 1 to look just like row 0 when clicked.

Possibly related: can I style the look of the hover / selection? Eg. to replace the blue gradient hover look (line 3) with a custom solid color. I have found this and this, unfortunately not helping.

(Achieving the same without using ListView is acceptable too. I'd just like to be able to use logical scrolling and UI virtualization as ListView does)

The XAML for ListView is:

<ListView Height="280" Name="listView">
    <ListView.Resources>
        <!-- attempt to override selection color -->
        <SolidColorBrush x:Key="{x:Static SystemColors.HighlightColorKey}"
                         Color="Green" />
    </ListView.Resources>
    <ListView.View>
        <GridView>
            <GridView.Columns>
                <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" />
                <!-- more columns -->
            </GridView.Columns>
        </GridView>
     </ListView.View>
</ListView>
Undesigning answered 26/6, 2009 at 20:46 Comment(2)
I've never used a ListView in WPF before, but I'm sure that there is some sort of IsEnabled property that, if set to false, would disable the entire control and would probably achieve what you're after, but I'm not 100% sure.Instrumentation
Hi, yes there is an IsEnabled property, which can disable the whole ListView. I need the ListView to be working normally though, just don't display the selection.Undesigning
O
161

Per Martin Konicek's comment, to fully disable the selection of the items in the simplest manner:

<ListView>
    <ListView.ItemContainerStyle>
        <Style TargetType="ListViewItem">
            <Setter Property="Focusable" Value="false"/>
        </Style>
    </ListView.ItemContainerStyle>
    ...
</ListView>

However if you still require the functionality of the ListView, like being able to select an item, then you can visually disable the styling of the selected item like so:

You can do this a number of ways, from changing the ListViewItem's ControlTemplate to just setting a style (much easier). You can create a style for the ListViewItems using the ItemContainerStyle and 'turn off' the background and border brush when it is selected.

<ListView>
    <ListView.ItemContainerStyle>
        <Style TargetType="{x:Type ListViewItem}">
            <Style.Triggers>
                <Trigger Property="IsSelected"
                         Value="True">
                    <Setter Property="Background"
                            Value="{x:Null}" />
                    <Setter Property="BorderBrush"
                            Value="{x:Null}" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </ListView.ItemContainerStyle>
    ...
</ListView>

Also, unless you have some other way of notifying the user when the item is selected (or just for testing) you can add a column to represent the value:

<GridViewColumn Header="IsSelected"
                DisplayMemberBinding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListViewItem}}, Path=IsSelected}" />
Overcareful answered 26/6, 2009 at 21:18 Comment(9)
Didn't see the related part, but you can do the same thing, setting the background and border as you like on the IsMouseOver property.Overcareful
Thanks a million, I wish I could donate some of my reputation to you. I also managed to style the rows to alternate colors: live.mscommunity.net/blogs/borissevo/archive/2008/10/21/… I find WPF a little unintuitive (I'm a beginner), I would never figure out to style ListViewItems as ItemContainerStyle, why is there no GridView.SelectedRowStyle, GridView.HoverRowStyle? Thank you!Undesigning
I solved it even better now - <Setter Property="Focusable" Value="false"/> completely disables selecting the row.Undesigning
Ahh, I thought you meant just turn off Selection visually. If you don't want them to be selected at all, you might want to take a look at using an ItemsControl (Since you can still set the selected items through code if they arn't focusable), though to get the Grid look you'll have to do something like this: manicprogrammer.com/cs/blogs/… Also, if you haven't yet, you may want to check out the book WPF Unleashed, as it provides a great introduction to WPF & XAML.Overcareful
Thanks for the tip and your help again. Dissabling the selection using Focusable is perfectly OK for me. I tried using the ItemsControl as in manicprogrammer.com/cs/blogs/willeke/archive/2007/08/08/…, but I am also using data virtualization based on codeproject.com/KB/WPF/WpfDataVirtualization.aspx, which did not work with ItemsControl (it enumerated whole IList at once). Also, I could not make the ItemsControl to use logical scrolling (although it may be possible).Undesigning
@MartinKonicek i know that is an old post but your high rated comment should be an answer ;)Isotherm
What is the difference b/w <Style TargetType="ListViewItem"> and <Style TargetType="{x:Type ListViewItem}">? Thanks so much.Aerate
@MartinKonicek I had to add BasedOn="{StaticResource {x:Type ListViewItem}}" so it didn't override the rest of my grid styles, but I also think you should make your comment the accepted answerLennielenno
In windows10, you also need a trigger to turn off the background when Property="IsMouseOver"Goatish
T
31

Moore's answer doesn't work, and the page here:

Specifying the Selection Color, Content Alignment, and Background Color for items in a ListBox

explains why it cannot work.

If your listview only contains basic text, the simplest way to solve the problem is by using transparent brushes.

<Window.Resources>
  <Style TargetType="{x:Type ListViewItem}">
    <Style.Resources>
      <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="#00000000"/>
      <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="#00000000"/>
    </Style.Resources>
  </Style>
</Window.Resources>

This will produce undesirable results if the listview's cells are holding controls such as comboboxes, since it also changes their color. To solve this problem, you must redefine the control's template.

  <Window.Resources>
    <Style TargetType="{x:Type ListViewItem}">
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="{x:Type ListViewItem}">
            <Border SnapsToDevicePixels="True" 
                    x:Name="Bd" 
                    Background="{TemplateBinding Background}" 
                    BorderBrush="{TemplateBinding BorderBrush}" 
                    BorderThickness="{TemplateBinding BorderThickness}" 
                    Padding="{TemplateBinding Padding}">
              <GridViewRowPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" 
                                    VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
                                    Columns="{TemplateBinding GridView.ColumnCollection}" 
                                    Content="{TemplateBinding Content}"/>
            </Border>
            <ControlTemplate.Triggers>
              <Trigger Property="IsEnabled" 
                       Value="False">
                <Setter Property="Foreground" 
                        Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
              </Trigger>
            </ControlTemplate.Triggers>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>
  </Window.Resources>
Trusting answered 11/7, 2010 at 13:57 Comment(1)
This makes all my items in my ListView disappearPittel
G
22

Set the style of each ListViewItem to have Focusable set to false.

<ListView ItemsSource="{Binding Test}" >
    <ListView.ItemContainerStyle>
        <Style TargetType="{x:Type ListViewItem}">
            <Setter Property="Focusable" Value="False"/>
        </Style>
    </ListView.ItemContainerStyle>
</ListView>
Gunter answered 7/11, 2014 at 15:23 Comment(1)
Simple and efficient. And it actually does what is asked : It turns off the selection instead of just hiding it. This is the best answer.Abney
E
15

Here's the default template for ListViewItem from Blend:

Default ListViewItem Template:

        <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>
                        <Trigger Property="IsSelected" Value="true">
                            <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
                        </Trigger>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="IsSelected" Value="true"/>
                                <Condition Property="Selector.IsSelectionActive" Value="false"/>
                            </MultiTrigger.Conditions>
                            <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
                            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}}"/>
                        </MultiTrigger>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>

Just remove the IsSelected Trigger and IsSelected/IsSelectionActive MultiTrigger, by adding the below code to your Style to replace the default template, and there will be no visual change when selected.

Solution to turn off the IsSelected property's visual changes:

    <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>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
Eisele answered 15/4, 2013 at 20:30 Comment(0)
U
13

The easiest way I found:

<Setter Property="Focusable" Value="false"/>
Undesigning answered 11/3, 2015 at 21:31 Comment(1)
@Mutex It does work - you have to apply this on ListView.ItemContainerStyle though!Penza
B
9

Okay, little late to the game, but none of these solutions quite did what I was trying to do. These solutions have a couple problems

  1. Disable the ListViewItem, which screws up the styles and disables all the children controls
  2. Remove from the hit-test stack, i.e. children controls never get a mouse-over or click
  3. Make it not focusable, this just plain didn't work for me?

I wanted a ListView with the grouping headers, and each ListViewItem should just be 'informational' without selection or hover over, but the ListViewItem has a button in it that I want to be click-able and have hover-over.

So, really what I want is the ListViewItem to not be a ListViewItem at all, So, I over rode the ListViewItem's ControlTemplate and just made it a simple ContentControl.

<ListView.ItemContainerStyle>
    <Style TargetType="ListViewItem">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                    <ContentControl Content="{Binding Content, RelativeSource={RelativeSource TemplatedParent}}"/>
                </ControlTemplate>
            </Setter.Value>
         </Setter>
     </Style>
</ListView.ItemContainerStyle>
Bifarious answered 1/10, 2016 at 18:59 Comment(1)
You've got a whole 'nother full-blown ContentControl nested as the template for your ListViewItem (i.e., also a ContentControl) template, which is either redundant or pointless. It's an easy error to make due to the similar names--you want the much lighter-weight ContentPresenter here, since it's designed for this purpose.Dutybound
F
8

Further to the solution above... I would use a MultiTrigger to allow the MouseOver highlights to continue to work after selection such that your ListViewItem's style will be:

        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Style.Triggers>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="IsSelected" Value="True" />
                            <Condition Property="IsMouseOver" Value="False" />
                        </MultiTrigger.Conditions>
                        <MultiTrigger.Setters>
                            <Setter Property="Background" Value="{x:Null}" />
                            <Setter Property="BorderBrush" Value="{x:Null}" />
                        </MultiTrigger.Setters>
                    </MultiTrigger>
                </Style.Triggers>
            </Style>
        </ListView.ItemContainerStyle>
Flagstone answered 5/11, 2009 at 20:39 Comment(0)
M
7

One of the properties of the listview is IsHitTestVisible. Uncheck it.

Ment answered 6/3, 2016 at 14:7 Comment(2)
Simple and effective, also solve my problem with ScrollViewer wrapped out side a list view.Rizzi
I got button template inside the listview itemtemplate. if deselect IsHitTestVisible the button cannot be clicked. It act like IsEnabled = false;Commend
F
5

Use the code below:

<ListView.ItemContainerStyle>
    <Style TargetType="{x:Type ListViewItem}">
        <Setter Property="Background" Value="Transparent" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListViewItem}">
                    <ContentPresenter />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ListView.ItemContainerStyle>
Fast answered 25/2, 2018 at 14:28 Comment(0)
N
2

This is for others who may encounter the following requirements:

  1. Completely replace the visual indication of "selected" (e.g. use some kind of shape), beyond just changing the color of the standard highlight
  2. Include this selected indication in the DataTemplate along with the other visual representations of your model, but,
  3. Don't want to have to add an "IsSelectedItem" property to your model class and be burdened with manually manipulating that property on all model objects.
  4. Require items to be selectable in the ListView
  5. Also would like to replace the visual representation of IsMouseOver

If you're like me (using WPF with .NET 4.5) and found that the solutions involving style triggers simply didn't work, here's my solution:

Replace the ControlTemplate of the ListViewItem in a style:

<ListView ItemsSource="{Binding MyStrings}" ItemTemplate="{StaticResource dtStrings}">
        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ListViewItem">
                            <ContentPresenter/>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ListView.ItemContainerStyle>
    </ListView>

..And the DataTemplate:

<DataTemplate x:Key="dtStrings">
        <Border Background="LightCoral" Width="80" Height="24" Margin="1">
            <Grid >
                <Border Grid.ColumnSpan="2" Background="#88FF0000" Visibility="{Binding RelativeSource={RelativeSource AncestorType=ListViewItem}, Path=IsMouseOver, Converter={StaticResource conBoolToVisibilityTrueIsVisibleFalseIsCollapsed}}"/>
                <Rectangle Grid.Column="0" Fill="Lime" Width="10" HorizontalAlignment="Left" Visibility="{Binding RelativeSource={RelativeSource AncestorType=ListViewItem}, Path=IsSelected, Converter={StaticResource conBoolToVisibilityTrueIsVisibleFalseIsCollapsed}}" />
                <TextBlock Grid.Column="1" Text="{Binding}" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" />
            </Grid>
        </Border>
    </DataTemplate>

Results in this at runtime (item 'B' is selected, item 'D' has mouse over):

ListView appearance

Noun answered 18/5, 2017 at 18:24 Comment(0)
N
2

Another similar control to ListView and ListBox that doesn't offer selection is ItemsControl, consider using that instead.

Nyctalopia answered 31/12, 2022 at 19:59 Comment(0)
J
1

One more way to disable selection.

    <ListView ...>
        <ListView.ItemsPanel>
            <ItemsPanelTemplate>
                <VirtualizingStackPanel IsEnabled="False"/>
            </ItemsPanelTemplate>
        </ListView.ItemsPanel>
    </ListView>

It's like

<ListView IsEnabled="False"> 

but without disabled scroller

Juvenilia answered 17/2, 2023 at 18:18 Comment(0)
B
0

Below code disables ListViewItem row selection and also allows to add padding, margin etc.

<ListView.ItemContainerStyle>                                                                              
   <Style TargetType="ListViewItem">                                                                                      
       <Setter Property="Template">                                                                                            
         <Setter.Value>                                                                                             
           <ControlTemplate TargetType="{x:Type ListViewItem}">                                                                                                    
              <ListViewItem Padding="0" Margin="0">                                                                                                        
                  <ContentPresenter />
              </ListViewItem>
           </ControlTemplate>                                                          
         </Setter.Value>                                                                                       
         </Setter>
      </Style>                                                                      
  </ListView.ItemContainerStyle> 
Bumbling answered 25/10, 2018 at 10:49 Comment(0)
G
0

Below code disable Focus on ListViewItem

<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
    <Setter Property="Background" Value="Transparent" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ListViewItem}">
                <ContentPresenter />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Gybe answered 8/10, 2019 at 19:24 Comment(0)
D
0
        <ListView Grid.Row="1" ItemsSource="{Binding Properties}" >
            <!--Disable selection of items-->
            <ListView.Resources>
                <Style TargetType="{x:Type ListViewItem}">
                    <Setter Property="Background" Value="Transparent" />
                    <Setter Property="BorderBrush" Value="Transparent"/>
                    <Setter Property="VerticalContentAlignment" Value="Center"/>
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type ListViewItem}">
                                <Grid Background="{TemplateBinding Background}">
                                    <Border Name="Selection" Visibility="Collapsed" />
                                    <!-- This is used when GridView is put inside the ListView -->
                                    <GridViewRowPresenter Grid.RowSpan="2"
                                      Margin="{TemplateBinding Padding}"
                                      HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                      VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                      SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>

                                </Grid>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </ListView.Resources>
            <ListView.View>
                <GridView>
                    <GridViewColumn Width="90" DisplayMemberBinding="{Binding Name}"  />
                    <GridViewColumn Width="90" CellTemplateSelector="{StaticResource customCellTemplateSelector}"  />
                </GridView>
            </ListView.View>
        </ListView>
Dakota answered 13/3, 2021 at 16:58 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.