Disable WPF TreeView (or TreeViewItem) selection?

19,610

Solution 1

Whenever an item is selected, you could "unselect" it. Ex. modify the code from http://www.codeproject.com/KB/WPF/TreeView_SelectionWPF.aspx or use a MVVM approach (see http://www.codeproject.com/KB/WPF/TreeViewWithViewModel.aspx) and always set IsSelected back to false.

Solution 2

Try this:

<Trigger Property="HasItems" Value="true">
   <Setter Property="Focusable" Value="false" />
</Trigger>

Solution 3

Based off of the links to the currently accepted answer, I implemented this in my project:

<ListView.ItemContainerStyle>
    <Style TargetType="{x:Type ListViewItem}">
        <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
    </Style>
</ListView.ItemContainerStyle>

Works for TreeViewItem as well. And in the view model:

protected bool _DisableSelection;
private bool _IsSelected;
public bool IsSelected
{
    get { return _IsSelected; }
    set
    {
        if (value == _IsSelected) return;
        _IsSelected = _DisableSelection ? false : value;
        NotifyPropertyChanged();
    }
}

Now you don't have to go hunting!

Solution 4

This did the trick for me (based on this answer, but no tied to item - selection is disabled whatsoever):

<TreeView>
  <TreeView.ItemContainerStyle>
    <Style TargetType="TreeViewItem">
      <Setter Property="Focusable" Value="False" />
    </Style>
  </TreeView.ItemContainerStyle>
</TreeView>

Solution 5

I decided to write a reusable behavior, HTH:

Namespace Components
  Public NotInheritable Class TreeViewBehavior

    Public Shared Function GetIsTransparent(
      ByVal element As TreeViewItem) As Boolean
      If element Is Nothing Then Throw New ArgumentNullException("element")
      Return element.GetValue(IsTransparentProperty)
    End Function
    Public Shared Sub SetIsTransparent(ByVal element As TreeViewItem,
                                       ByVal value As Boolean)
      If element Is Nothing Then Throw New ArgumentNullException("element")
      element.SetValue(IsTransparentProperty, value)
    End Sub
    Public Shared ReadOnly IsTransparentProperty As DependencyProperty =
      DependencyProperty.RegisterAttached("IsTransparent", GetType(Boolean),
        GetType(TreeViewBehavior),
        New FrameworkPropertyMetadata(False,
          AddressOf IsTransparent_PropertyChanged))
    Private Shared Sub IsTransparent_PropertyChanged(
      ByVal sender As Object, ByVal e As DependencyPropertyChangedEventArgs)
      Dim tvi = DirectCast(sender, TreeViewItem)
      Dim isTransparent = CBool(e.NewValue)

      If isTransparent Then
        AddHandler tvi.Selected, AddressOf tvi_Selected
      Else
        RemoveHandler tvi.Selected, AddressOf tvi_Selected
      End If
    End Sub
    Private Shared Sub tvi_Selected(ByVal sender As Object,
                                    ByVal e As RoutedEventArgs)
      Dim treeViewItem = DirectCast(sender, TreeViewItem)
      If Not treeViewItem.IsSelected Then Exit Sub

      treeViewItem.Dispatcher.Invoke(
        Sub(tvi As TreeViewItem) tvi.IsSelected = False,
        System.Windows.Threading.DispatcherPriority.Send,
        treeViewItem)
    End Sub

  End Class
End Namespace

Usage:

<Window xmlns:components="clr-namespace:WpfApplication.Components">
  <TreeView>
    <TreeView.ItemContainerStyle>
      <Style TargetType="TreeViewItem">
        <Setter 
          Property="components:TreeViewBehavior.IsTransparent" 
          Value="True" />
      </Style>
    </TreeView.ItemContainerStyle>
  </TreeView>
</Window> 
Share:
19,610
Shimmy Weitzhandler
Author by

Shimmy Weitzhandler

Updated on June 05, 2022

Comments

  • Shimmy Weitzhandler
    Shimmy Weitzhandler almost 2 years

    Is there a nice way (except retemplating the whole TreeViewItem.Template) to disable selection in TreeView?

    I am basically looking for the ItemsControl style of the TreeView (An ItemsControl is the best use to 'disable' selection on ListBox, read this post)

  • Kev
    Kev over 11 years
    Whilst this may theoretically answer the question, we would like you to include the essential parts of the linked article in your answer, and provide the link for reference. Failing to do that leaves the answer at risk from link rot.
  • svick
    svick over 11 years
    There doesn't seem to be any PreviewSelected event on the WPF TreeView.
  • Danield
    Danield over 11 years
    hmm I was using Telerik's RadTreeView and I guess that I assumed that the PreviewSelected event was available in a regular TreeView.
  • ravuya
    ravuya about 8 years
    To extend this answer, setting Focusable to false on leaf TreeViewItems also appears to prevent them from being selected.
  • Ravid Goldenberg
    Ravid Goldenberg over 5 years
    It also prevent nodes without children from being selected, consider that.
  • Wobbles
    Wobbles almost 5 years
    Unfortunately when collapsing a node this can still result in the root getting selection
  • Neo Anderson
    Neo Anderson over 3 years
    While this code snippet may be the solution, including an explanation really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion.
  • CongoTM
    CongoTM over 3 years
    Thanks @NeoAnderson. I'm new here, but I just want to help.
  • Neo Anderson
    Neo Anderson over 3 years
    We all want to help. The goal is to do it as efficient as we can. Thanks for explaining the code snippet.