WPF Double Click TreeviewItem Child Node
Asked Answered
B

3

13

I have a treeview Item as such in a treeview that will have a list bound to it:

        <TreeViewItem Name="tviOffline" Foreground="Red" FontWeight="Bold"
                      Header="Offline">
            <TreeViewItem.ItemTemplate>
                <DataTemplate DataType="{x:Type local:Buddy}">
                    <StackPanel>
                        <TextBlock Text="{Binding Nick}" FontSize="10" Foreground="#8CFFD528" />
                    </StackPanel>
                </DataTemplate>
            </TreeViewItem.ItemTemplate>
        </TreeViewItem>

I cannot figure out how to get each of its childs to have a double click event.

any help is appreciated. thanks much.

Babby answered 28/11, 2010 at 7:59 Comment(0)
G
30
<TreeView.ItemContainerStyle>
    <Style TargetType="{x:Type TreeViewItem}">
        <EventSetter Event="MouseDoubleClick" Handler="OnItemMouseDoubleClick" />
        ...
Gamophyllous answered 28/11, 2010 at 8:1 Comment(1)
Huh. That was much easier than expected.Recommend
B
19
<TreeView.ItemContainerStyle>
    <Style TargetType="{x:Type TreeViewItem}">
        <EventSetter Event="MouseDoubleClick" Handler="OnItemMouseDoubleClick" />
        ...

And THEN, the handler has to be written as follows in order to prevent the double-click from firing on successive parent TreeViewItems:

   private void OnItemMouseDoubleClick(object sender, MouseButtonEventArgs args)
    {
        if (sender is TreeViewItem)
        {
            if (!((TreeViewItem)sender).IsSelected)
            {
                return;
            }
        }

        .... do stuff.

    }

Thanks to Aurelien Ribon for getting 90% of the way there. The double-click problem seems to be well-known in other postings on Stack Exchange. Just consolidating both solutions into one answer.

Bosh answered 2/2, 2014 at 21:53 Comment(2)
Thanks - now I know there's actually no need to do upward search in the visual tree to look for a TreeItem, if your event is set on the ItemContainerStyle.Garnishment
It is important to set the MouseButtonEventArgs as handled to prevent propagation. Don't forget to add e.Handled = true; (or args.Handled = true in this case). I had a case of this recently where a TextInput event was changing the focus to a different control because I forgot to mark it as handled.Trustworthy
F
5

This is the only way I managed to get it to work for all the cases:

    void MyTreeView_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
    {
        var clickedItem = TryGetClickedItem(myTreeView, e);
        if (clickedItem == null)
            return;

        e.Handled = true; // to cancel expanded/collapsed toggle
        DoStuff(clickedItem);
    }

    TreeViewItem TryGetClickedItem(TreeView treeView, MouseButtonEventArgs e)
    {
        var hit = e.OriginalSource as DependencyObject;
        while (hit != null && !(hit is TreeViewItem))
            hit = VisualTreeHelper.GetParent(hit);

        return hit as TreeViewItem;
    }
Fruitful answered 4/1, 2017 at 11:26 Comment(1)
Simpler yet, instead of your TryGetClickedItem, I just used hit.GetVisualParent<TreeViewItem>().Spiv

© 2022 - 2024 — McMap. All rights reserved.