1

How can I disable tree items collapsing/expanding when I double-click on tree item? I still would like to do this by clicking on toggle button, but not when I double-click on item.

This is XAML I have:

<TreeView Grid.Column="0" Grid.Row="0" ItemsSource="{Binding Categories}" helpers:TreeViewHelper.SelectedItem="{Binding SelectedCategory, Mode=TwoWay}" >
    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="IsExpanded" Value="True"/>
        </Style>
    </TreeView.ItemContainerStyle>
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate DataType="{x:Type core:Category}" ItemsSource="{Binding SubCategories}">
            <Label Content="{Binding Name}">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="MouseDoubleClick">
                        <i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=DataContext.CreateGroupsFromCategoryCommand , Mode=OneWay}" CommandParameter="{Binding}" />
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </Label>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

I would like to do this only in XAML.

Thank you for your help.

bacil82
  • 11
  • 1
  • 3

4 Answers4

1

You should suppress the double click event on treeviewitem:

<TreeView Grid.Column="0" Grid.Row="0" ItemsSource="{Binding Categories}" helpers:TreeViewHelper.SelectedItem="{Binding SelectedCategory, Mode=TwoWay}" TreeViewItem.PreviewMouseDoubleClick="TreeViewItem_PreviewMouseDoubleClick" >
    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="IsExpanded" Value="True"/>
        </Style>
    </TreeView.ItemContainerStyle>
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate DataType="{x:Type core:Category}" ItemsSource="{Binding SubCategories}">
            <Label Content="{Binding Name}">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="MouseDoubleClick">
                        <i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=DataContext.CreateGroupsFromCategoryCommand , Mode=OneWay}" CommandParameter="{Binding}" />
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </Label>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

Code Behind:

private void TreeViewItem_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
    //this will suppress the event that is causing the nodes to expand/contract 
    e.Handled = true;
}
Cinchoo
  • 6,088
  • 2
  • 19
  • 34
  • This is unfortunatelly not working as expected. I have special functionality on double-click via event trigger, and using this approach, the command invocation is supressed as well. Other problem is, that if you click fast multiple times on item, the item is ocassionaly still collapsed/expanded – bacil82 Nov 26 '18 at 18:51
0

You could implement a custom EventTrigger in your views code behind, as suggested here: https://stackoverflow.com/a/7688249/1206431

public class HandlingEventTrigger : System.Windows.Interactivity.EventTrigger
{
    protected override void OnEvent(System.EventArgs eventArgs)
    {
        var routedEventArgs = eventArgs as RoutedEventArgs;
        if (routedEventArgs != null)
            routedEventArgs.Handled = true;

        base.OnEvent(eventArgs);
    }
}

Add the namespace to your view like this xmlns:views="clr-namespace:YourNamespace.Views"

And then replace <i:EventTrigger EventName="MouseDoubleClick"> with <local:HandlingEventTrigger EventName="PreviewMouseDoubleClick">.

The HandlingEventTrigger will stop the event from being passed further up the visual tree and therefore not expanding/collapsing your tree, and using PreviewMouseDoubleClick instead of MouseDoubleClick will allow you to still fire your own command.

RonnyR
  • 210
  • 1
  • 5
0

XAML:

<TreeView x:Name="TreeView1" MouseDoubleClick="TreeView1_MouseDoubleClick" />

C# Code:

private void TreeView1_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
    e.Handled = true;
}

Works fine for me.

SkyDancer
  • 129
  • 1
  • 4
  • 13
  • A good answer will always include an explanation why this would solve the issue, so that the OP and any future readers can learn from it. – Tyler2P Dec 08 '21 at 22:34
0

I know this issue is old, but I found a slightly different way that preserves the wanted double-click behavior but stops the expand/collapse in case it helps someone.

Keep your typical double click method:

private void OnMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
   // Do something
}

Create an inherited class from TreeView (such as MyTreeView). Add the following to that inherited class:

    protected override void OnMouseDoubleClick(MouseButtonEventArgs e)
    {
        var tvi = GetTreeViewItemFromObject(ItemContainerGenerator, SelectedItem);
        if (tvi != null) tvi.IsExpanded = true;

        base.OnMouseDoubleClick(e);
    }

    /// <summary>
    /// Use the object to get its Tree View item
    /// </summary>
    /// <param name="container"></param>
    /// <param name="targetObject"></param>
    /// <returns></returns>
    private TreeViewItem GetTreeViewItemFromObject(ItemContainerGenerator container, object targetObject)
    {
        if (container.ContainerFromItem(targetObject) is TreeViewItem target) return target;
        for (int i = 0; i < container.Items.Count; i++)
            if ((container.ContainerFromIndex(i) as TreeViewItem)?.ItemContainerGenerator is ItemContainerGenerator childContainer)
                if (GetTreeViewItemFromObject(childContainer, targetObject) is TreeViewItem childTarget) return childTarget;
        return null;
    }

The GetTreeViewItemFromObject method was lifted from someplace else. I don't remember where.

RevitArkitek
  • 161
  • 7