Page 1 of 1

DoubleClick Treeview Node problem

Posted: Thu Sep 13, 2018 12:55 pm
by ALIENQuake
Hi,

The code below works as deigned. No matter how fast I execute doubleclick, I will always have child nodes checked or unchecked and the checkbox of the parent not will reflect the state of child nodes:

Code: Select all

[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")

function checkChildNode($node) {
    $checkStatus = $node.checked
    foreach ($n in $node.nodes) {
        $n.checked = $checkstatus
        checkChildNode($n)
    }
}

function checkParentNode($node) {
 $parent = $node.parent
 if($parent -eq $null) {
   return
 }
 $parent.checked = $true

  checkparentNode($parent)
}

$form = New-Object System.Windows.Forms.Form

$treeView = New-Object System.Windows.Forms.TreeView
$treeView.Dock = 'Fill'
$treeView.CheckBoxes = $true

$N1 = $treeView.Nodes.Add('Category 1')
$N2 = $treeView.Nodes.Add('Category 2')
$N3 = $treeView.Nodes.Add('Category 3')

$newNode = New-Object System.Windows.Forms.TreeNode
$newNode.Name = 'Test-A'
$newNode.Text = 'Test-A'
$N1.Nodes.Add($newNode)

$newNode = New-Object System.Windows.Forms.TreeNode
$newNode.Name = 'Test-B'
$newNode.Text = 'Test-B'
$N1.Nodes.Add($newNode)

$newNode = New-Object System.Windows.Forms.TreeNode
$newNode.Name = 'Component 0'
$newNode.Text = 'Component 0'
$N1.Nodes.Add($newNode) | Out-Null

$newNode = New-Object System.Windows.Forms.TreeNode
$newNode.Name = 'Component 1'
$newNode.Text = 'Component 1'
$N1.Nodes.Add($newNode) | Out-Null

# There can be deeper levels of treenodes

$TV_AfterCheck = {
    $treeView.Remove_AfterCheck($TV_AfterCheck)
    checkChildNode($_.node)
    checkParentNode($_.node)
    $treeView.Add_AfterCheck($TV_AfterCheck)
}

$treeView.Add_AfterCheck($TV_AfterCheck)
$form.Controls.Add($treeView)
$form.ShowDialog()
But doing the same for SAPIEN Forms, will produce weird behavior: sometimes parent node is checked while all child nodes not, just download attachment and click/doubleclick on the checkbox to observe weird behavior.
TreeView.psf
(18 KiB) Downloaded 174 times
Anybody know the reason why?

Re: DoubleClick Treeview Node problem

Posted: Thu Sep 13, 2018 6:11 pm
by jvierra
Try this:

Re: DoubleClick Treeview Node problem

Posted: Fri Sep 14, 2018 1:24 am
by jvierra
Here is the official Microsoft method from the SDK. It uses only one recursive function.

Re: DoubleClick Treeview Node problem

Posted: Fri Sep 14, 2018 1:46 pm
by ALIENQuake
TreeView2 doesn't handle click/doubleclicks correctly
TreeView3 has the same fault: https://s1.webmshare.com/EKAeY.webm

Google says that I need to override TreeView Class and use custom ones for all forms. I assume that's not possible, right?

Re: DoubleClick Treeview Node problem

Posted: Fri Sep 14, 2018 2:08 pm
by jvierra
Google knows not where-from they speak.

The only way to modify the double-click is to create a new treeview which is why most programmers never use it to manage checkboxes. Even "overriding" the class cannot do this.

You issue has been an issue with programmers since the fist version of the control 2 decades ago. While there are ways to modify the message loop in a compiled language it is never a clean solution.

The design of the treeview is that the double-click "selects" a node. You can use the event to also set the check bt internal condition can cause this to fail.

There are many third party treeview replacements that address this issue in various ways.

My best recommendation is to modify you USE case and design to avoid the issue and use the last code I posted to handle mass checking and unchecking and accept that as the best method.

The method most of us have used over the years has been to use a right context menu to do group checking. This avoids the issue with event cascading.

Code: Select all

$treeviewNav_AfterCheck=[System.Windows.Forms.TreeViewEventHandler]{
#Event Argument: $_ = [System.Windows.Forms.TreeViewEventArgs]
   if($_.Action -ne 'Unknown'){
      if($_.Node.Nodes.Count -gt 0){
         CheckAllChildNodes $_.Node $_.Node.Checked
      }
   }
}
Note the use of "Action". This was the part I couldn't remember until I looked at the old SDK example.

The only missing code here is the reverse recursion up the ancestor nodes to set the check correctly.

If you look closely at this code:

Re: DoubleClick Treeview Node problem

Posted: Fri Sep 14, 2018 2:29 pm
by jvierra
The following code will block the annoying expanding and collapsing with a double-click.

Code: Select all

$treeviewNav_BeforeExpand=[System.Windows.Forms.TreeViewCancelEventHandler]{
#Event Argument: $_ = [System.Windows.Forms.TreeViewCancelEventArgs]
    if($_.Action -eq 'ByMouse'){$_.Cancel = $true}
}
You can now use the doubleclick event to force a check.