locked
ListView, I would like somthing like SelectionMode.None ? RRS feed

  • Question

  • I know it’s a little odd. But is there a way to make the ListView “readonly”. I was thinking something in the line of:

    ListView1.SelectionMode = SelectionMode.None;

    I know I could just ignore the SelectionChanged event. But the problem is that the styling shows that an item is selected.

    Best regards,
      Thomas S. Andersen

     

    BTW, as a workaround I'm using this at the moment:

    ListView1.SelectionChanged += delegate(object sender, SelectionChangedEventArgs e)
    {
        (sender
    as ListView).SelectedItem = null;
    };

     

    Wednesday, April 26, 2006 12:25 PM

Answers

  • You should just be able to change/remove the style for a selected ListItem so it doesn't look selected. See below for the default template of a ListItem, you can just remove the trigger for IsSelected and the MultiTrigger that has a condition on it (both highlighted in red).

    HTH,
    Drew

    <Style x:Key="ListBoxItemStyle1" TargetType="{x:Type ListBoxItem}">
       <Setter Property="Background" Value="#00FFFFFF"/>
       <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorLevel=1, Mode=FindAncestor, AncestorType={x:Type ItemsControl}}}"/>
       <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorLevel=1, Mode=FindAncestor, AncestorType={x:Type ItemsControl}}}"/>
       <Setter Property="Padding" Value="1,0,0,0"/>
       <Setter Property="Template">
        <Setter.Value>
         <ControlTemplate TargetType="{x:Type ListBoxItem}">
          <Border Background="{TemplateBinding Background}" x:Name="Bd" SnapsToDevicePixels="True" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}">
           <ContentPresenter DataContext="{x:Null}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" x:Name="ContentPresenter" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"/>
          </Border>
          <ControlTemplate.Triggers>
           <Trigger Property="IsSelected" Value="True">
            <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" TargetName="Bd"/>
            <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" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" TargetName="Bd"/>
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
           </MultiTrigger>
           <Trigger Property="IsEnabled" Value="False">
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
           </Trigger>
          </ControlTemplate.Triggers>
         </ControlTemplate>
        </Setter.Value>
       </Setter>
      </Style>

    Wednesday, April 26, 2006 2:27 PM
  • If you do not want selection why use a List?  You could use many other controls to display a collection of objects.  If you want to switch between enabled/disabled modes that might make sense.  In which case you may want to try setting IsEnabled to false.  You can of course combine this with restyling as also suggested.
    Wednesday, April 26, 2006 3:31 PM
  • Hello, Thomas

    I think you can achieve it by hooking ListView.SelectionChanged Event and adding ListView.SelectedItems.Clear() inside the event. It looks a tricky way, but it works.

     

    Thanks,

    Ji

    Tuesday, May 9, 2006 9:40 AM

All replies

  • You should just be able to change/remove the style for a selected ListItem so it doesn't look selected. See below for the default template of a ListItem, you can just remove the trigger for IsSelected and the MultiTrigger that has a condition on it (both highlighted in red).

    HTH,
    Drew

    <Style x:Key="ListBoxItemStyle1" TargetType="{x:Type ListBoxItem}">
       <Setter Property="Background" Value="#00FFFFFF"/>
       <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorLevel=1, Mode=FindAncestor, AncestorType={x:Type ItemsControl}}}"/>
       <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorLevel=1, Mode=FindAncestor, AncestorType={x:Type ItemsControl}}}"/>
       <Setter Property="Padding" Value="1,0,0,0"/>
       <Setter Property="Template">
        <Setter.Value>
         <ControlTemplate TargetType="{x:Type ListBoxItem}">
          <Border Background="{TemplateBinding Background}" x:Name="Bd" SnapsToDevicePixels="True" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}">
           <ContentPresenter DataContext="{x:Null}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" x:Name="ContentPresenter" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"/>
          </Border>
          <ControlTemplate.Triggers>
           <Trigger Property="IsSelected" Value="True">
            <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" TargetName="Bd"/>
            <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" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" TargetName="Bd"/>
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
           </MultiTrigger>
           <Trigger Property="IsEnabled" Value="False">
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
           </Trigger>
          </ControlTemplate.Triggers>
         </ControlTemplate>
        </Setter.Value>
       </Setter>
      </Style>

    Wednesday, April 26, 2006 2:27 PM
  • If you do not want selection why use a List?  You could use many other controls to display a collection of objects.  If you want to switch between enabled/disabled modes that might make sense.  In which case you may want to try setting IsEnabled to false.  You can of course combine this with restyling as also suggested.
    Wednesday, April 26, 2006 3:31 PM
  • Drew:
    I can’t change the style, because our application will support (runtime loaded) customer styling.
    But thanks for the xaml paste, it is very informative.

    Michael:
    IsEnabled doesn’t do the job for me, because it disables the control and scrolling option.


    Scenario: The reason I need a “ReadOnly” option is that I have made a derived listbox that takes a DataTable as the DateSource and creates a nice View.
    But on some cases; for example when it is used as a search-result viewer, the user should be able to select a search result to go to the record. But in other cases it is used for displaying some simple data like “Record history log” (showing who at what has changed this record through time).

     

    Thursday, April 27, 2006 6:58 AM
  • Hello, Thomas

    I think you can achieve it by hooking ListView.SelectionChanged Event and adding ListView.SelectedItems.Clear() inside the event. It looks a tricky way, but it works.

     

    Thanks,

    Ji

    Tuesday, May 9, 2006 9:40 AM
  • I know the reply is a bit old, but I was stumbling around this as well (as in pre-WPF world we had to use ListBox/ListView types of controls for list).

    Currently the clean solution is to use ItemsControl. That allows using same template structure that ListView allows, but it does not have the selection logic. Below is example XAML (including also one way of define the layout of panel how you want the items to be listed):

    <ItemsControl ItemsSource="{Binding}" ItemTemplate="{StaticResource StatStatic}">

    <ItemsControl.ItemsPanel>

    <ItemsPanelTemplate>

    <StackPanel Orientation="Horizontal" />

    </ItemsPanelTemplate>

    </ItemsControl.ItemsPanel>

    </ItemsControl>

    • Proposed as answer by Rajeshaz09 Tuesday, October 21, 2008 8:33 AM
    Tuesday, August 1, 2006 6:12 AM
  • This seems to work just fine...

     

    private void lvItems_SelectionChanged(Object sender, SelectionChangedEventArgs e) {

    try {

    lvItems.SelectedIndex = -1;

    } catch(Exception ex) {

    App.DisplayAndLogException(ex);

    }

    }

    Thursday, January 24, 2008 11:18 PM
  • You could also add a Rectangle control, with the Fill set to Transparent, and it's location set to the same as the ListView.
    Bill Gates look out!
    Sunday, September 27, 2009 5:06 PM
  • IMHO, 'None' should be added to the SelectionMode enum.
    Shimmy
    Monday, January 11, 2010 4:36 AM
  • Hey Latta LIKE WHAT?
    Tuesday, March 16, 2010 7:37 PM
  • Yikes. A lot of solutions, but they all seem unnecessarily complicated.

    Just use ItemsCollection. ListView is a subclass of ItemsCollection with the addition of selection capabilities. If you use an ItemsCollection in your XAML instead of a ListView, you'll get all the capabilities of a ListView except SelectedItem and associated properties, which is effectively SelectionMode.None.

    • Proposed as answer by regensteinj Thursday, February 23, 2012 12:50 PM
    Saturday, December 18, 2010 8:27 PM
  • You're wrong my friend.

    We do want to enable selection sometime, we just want to disable selection of the ListBox.


    Shimmy
    Saturday, December 18, 2010 10:03 PM
  • I'm not super familar with all the WPF classes so this really helped me get what I wanted. Thanks a lot.

    Wednesday, October 19, 2011 11:10 PM