views:

5365

answers:

4

Hi everyone,

I have a simple WPF ListView and a simple question:

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

ListView

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)

Thank you very much for your help.

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

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.

James McConnell
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.
Martin Konicek
Ah, my bad, I misunderstood what you were looking for.
James McConnell
Thanks for your effort anyway..
Martin Konicek
+10  A: 

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}" />
rmoore
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.
rmoore
Thanks a million, I wish I could donate some of my reputation to you. I also managed to style the rows to alternate colors: http://live.mscommunity.net/blogs/borissevo/archive/2008/10/21/wpf-trick-1-alternate-background-colors-for-listview-rows.aspxI 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!
Martin Konicek
I solved it even better now - <Setter Property="Focusable" Value="false"/> completely disables selecting the row.
Martin Konicek
rmoore
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 http://manicprogrammer.com/cs/blogs/willeke/archive/2007/08/08/listview-gridview-selection-itemscontrol-gridviewheaderrowpresenter-gridviewrowpresenter.aspx, but I am also using data virtualization based on http://www.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).
Martin Konicek
+1  A: 

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>
Reddog
+2  A: 

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

link text

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