locked
VB Treeview event NodeMouseClick raised on node double click !!! How to avoid this. RRS feed

  • Question

  • Hi,

    I have a problem with the Treeview control, when I try to use the NodeMouseDoubleClick event the even NodeMouseClick is also fired just before ...

    Anyone can explain me how to avoid the NodeMouseClick event to be raised on a node double click.

    Here's a simple example to reproduce the behavior:

    Imports System.IO
    Public Class Form1
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Try
                Dim rootNode As New TreeNode
                rootNode.Text = "C:\Temp"
                TreeView1.Nodes.Add(rootNode)
    
                Dim di As DirectoryInfo = New DirectoryInfo(rootNode.Text)
                Dim flds() As DirectoryInfo = di.GetDirectories("*")
                Dim rNode As TreeNode
    
                If flds.Count <> 0 Then
                    For Each fldt As DirectoryInfo In flds
                        rNode = New TreeNode
                        rNode.Name = fldt.Name
                        rNode.Text = rNode.Name
                        TreeView1.TopNode.Nodes.Add(rNode)
    
                        Dim subDir() As DirectoryInfo = fldt.GetDirectories("*")
                        If subDir.Count > 0 Then
                            rNode.Nodes.Add("Dummy")
                        End If
                    Next
                End If
    
            Catch ex As Exception
                MsgBox(ex.Message & vbNewLine & vbNewLine & ex.StackTrace)
            End Try
        End Sub
    
        Private Sub TreeView1_NodeMouseClick(sender As Object, e As TreeNodeMouseClickEventArgs) Handles TreeView1.NodeMouseClick
            Debug.Print("Node Mouse Click - Number of click: " & e.Clicks)
        End Sub
    
        Private Sub TreeView1_NodeMouseDoubleClick(sender As Object, e As TreeNodeMouseClickEventArgs) Handles TreeView1.NodeMouseDoubleClick
            Debug.Print("Node Mouse Double Click - Number of click: " & e.Clicks)
        End Sub
        Private Sub TreeView1_MouseClick(sender As Object, e As MouseEventArgs) Handles TreeView1.MouseClick
            Debug.Print("Mouse Click - Number of click: " & e.Clicks)
        End Sub
        Private Sub TreeView1_MouseDoubleClick(sender As Object, e As MouseEventArgs) Handles TreeView1.MouseDoubleClick
            Debug.Print("Mouse Double Click - Number of click: " & e.Clicks)
        End Sub
    End Class
    Regards

    • Edited by Alex Cote Monday, May 4, 2020 3:24 PM Edit to code
    Monday, May 4, 2020 3:12 PM

Answers

  • The system cannot predict the future: when you click the node, it does not know that you are going to click it again.

    In order to postpone the reaction to mouse clicks until a possible double click is received, try a timer (Timer component, which can be inserted in Form designer).

    In NodeMouseClick: start the timer. The interval is SystemInformation.DoubleClickTime+10.

    In NodeMouseDoubleClick: stop the timer and perform the actions for double-clicks.

    In Tick event of timer: stop the timer and perform the actions for simple clicks.

    • Marked as answer by Alex Cote Tuesday, May 5, 2020 4:40 PM
    Tuesday, May 5, 2020 8:11 AM

All replies

  • Hi,

    How about using a boolean-variable like this?
    Private Sub TreeView1_NodeMouseClick(sender As Object, e As TreeNodeMouseClickEventArgs) Handles TreeView1.NodeMouseClick
        If (Me.Ignore_MouseClick) Then
            Me.Ignore_MouseClick = False
        Else
            Debug.Print("Node Mouse Click - Number of click: " & e.Clicks)
        End If
    End Sub
    
    Private Sub TreeView1_NodeMouseDoubleClick(sender As Object, e As TreeNodeMouseClickEventArgs) Handles TreeView1.NodeMouseDoubleClick
        Me.Ignore_MouseClick = True
        Debug.Print("Node Mouse Double Click - Number of click: " & e.Clicks)
    End Sub
    
    Private Sub TreeView1_MouseClick(sender As Object, e As MouseEventArgs) Handles TreeView1.MouseClick
        If (Me.Ignore_MouseClick) Then
            Me.Ignore_MouseClick = False
        Else
            Debug.Print("Mouse Click - Number of click: " & e.Clicks)
        End If
    End Sub
    
    Private Sub TreeView1_MouseDoubleClick(sender As Object, e As MouseEventArgs) Handles TreeView1.MouseDoubleClick
        Me.Ignore_MouseClick = True
        Debug.Print("Mouse Double Click - Number of click: " & e.Clicks)
    End Sub
    [note]
      A variable "Ignore_MouseClick" needs to be defined in Class.
    Private Ignore_MouseClick As Boolean = False
    Regards,

    Ashidacchi -- http://hokusosha.com

    Tuesday, May 5, 2020 12:09 AM
  • The system cannot predict the future: when you click the node, it does not know that you are going to click it again.

    In order to postpone the reaction to mouse clicks until a possible double click is received, try a timer (Timer component, which can be inserted in Form designer).

    In NodeMouseClick: start the timer. The interval is SystemInformation.DoubleClickTime+10.

    In NodeMouseDoubleClick: stop the timer and perform the actions for double-clicks.

    In Tick event of timer: stop the timer and perform the actions for simple clicks.

    • Marked as answer by Alex Cote Tuesday, May 5, 2020 4:40 PM
    Tuesday, May 5, 2020 8:11 AM
  • Thanks for having taken the time to respond.

    Unfortunately I do not see how this method will allow me to manage Simple click and Double click on my Treeview object.

    Tuesday, May 5, 2020 2:00 PM
  • Hi,

    I like that idea, will try to implement that solution.

    Edit: Works fine, thanks for the solution.

    Regards


    • Edited by Alex Cote Tuesday, May 5, 2020 4:42 PM
    Tuesday, May 5, 2020 3:08 PM
  • Hi,
    try this demo:

    Public Class Form96
    
      Private WithEvents tv As New TreeView With {.Dock = DockStyle.Fill}
      Private lb As New ListBox With {.Dock = DockStyle.Bottom}
      Private Sub Form96_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Me.Controls.AddRange(New Control() {tv, lb})
        For i = 1 To 10
          tv.Nodes.Add(New TreeNode With {.Text = $"Node {i}"})
        Next
      End Sub
    
      Private sw1 As Boolean
      Private Async Sub TreeView1_NodeMouseClick(sender As Object, e As TreeNodeMouseClickEventArgs) Handles tv.NodeMouseClick
        sw1 = False
        Await Task.Delay(SystemInformation.DoubleClickTime + 2)
        If sw1 Then
          lb.Items.Insert(0, $"{Now:mm:ss.fff} Node Mouse Double Click - Number of click: {e.Clicks}")
        Else
          lb.Items.Insert(0, $"{Now:mm:ss.fff} Node Mouse Click - Number of click: {e.Clicks}")
        End If
      End Sub
      Private Sub TreeView1_NodeMouseDoubleClick(sender As Object, e As TreeNodeMouseClickEventArgs) Handles tv.NodeMouseDoubleClick
        sw1 = True
      End Sub
    
      Private sw2 As Boolean
      Private Async Sub TreeView1_MouseClick(sender As Object, e As MouseEventArgs) Handles tv.MouseClick
        sw2 = False
        Await Task.Delay(SystemInformation.DoubleClickTime + 2)
        If sw2 Then
          lb.Items.Insert(0, $"{Now:mm:ss.fff} Mouse Double Click - Number of click: {e.Clicks}")
        Else
          lb.Items.Insert(0, $"{Now:mm:ss.fff} Mouse Click - Number of click: {e.Clicks}")
        End If
      End Sub
      Private Sub TreeView1_MouseDoubleClick(sender As Object, e As MouseEventArgs) Handles tv.MouseDoubleClick
        sw2 = True
      End Sub
    
    End Class


    --
    Best Regards / Viele Grüße
    Peter Fleischer (former MVP for Developer Technologies)
    Homepage, Tipps, Tricks

    Tuesday, May 5, 2020 5:10 PM