DoubleClick Treeview Node problem

Ask questions about creating Graphical User Interfaces (GUI) in PowerShell and using WinForms controls.
Forum rules
Do not post any licensing information in this forum.

Any code longer than three lines should be added as code using the 'Select Code' dropdown menu or attached as a file.
Post Reply
User avatar
ALIENQuake
Posts: 26
Joined: Sun Mar 03, 2013 12:45 pm

DoubleClick Treeview Node problem

Post by ALIENQuake » Thu Sep 13, 2018 12:55 pm

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 4 times
Anybody know the reason why?

User avatar
jvierra
Posts: 12678
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: DoubleClick Treeview Node problem

Post by jvierra » Thu Sep 13, 2018 6:11 pm

Try this:
Attachments
TreeView2.psf
(16.1 KiB) Downloaded 4 times

User avatar
jvierra
Posts: 12678
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: DoubleClick Treeview Node problem

Post by jvierra » Fri Sep 14, 2018 1:24 am

Here is the official Microsoft method from the SDK. It uses only one recursive function.
Attachments
TreeView3.psf
(16.25 KiB) Downloaded 4 times

User avatar
ALIENQuake
Posts: 26
Joined: Sun Mar 03, 2013 12:45 pm

Re: DoubleClick Treeview Node problem

Post by ALIENQuake » Fri Sep 14, 2018 1:46 pm

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?

User avatar
jvierra
Posts: 12678
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: DoubleClick Treeview Node problem

Post by jvierra » Fri Sep 14, 2018 2:08 pm

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:

User avatar
jvierra
Posts: 12678
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: DoubleClick Treeview Node problem

Post by jvierra » Fri Sep 14, 2018 2:29 pm

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.

Post Reply