PowerShell .NET模仿treenodes的Windows默认复选框行为

时间:2015-01-12 10:50:10

标签: .net winforms forms powershell

在我们的Windows.Forms表格中,我们正在努力实现以下目标:

  1. 选中/取消选中父节点时,选中/取消选中所有子节点。
  2. 如果检查了所有子节点,则自动检查父节点。
  3. 如果取消选中其中一个子节点,则取消选中父节点。
  4. 测试代码:

    $form = New-Object System.Windows.Forms.Form
    
    $treeView = New-Object System.Windows.Forms.TreeView
    $treeView.Dock = 'Fill'
    $treeView.CheckBoxes = $true
    
    $N1 = $treeView.Nodes.Add('Node 1')
    $N2 = $treeView.Nodes.Add('Node 2')
    $N3 = $treeView.Nodes.Add('Node 3')
    
    $newNode = New-Object System.Windows.Forms.TreeNode  
    $newNode.Name = 'Node 1 Sub 1'
    $newNode.Text = 'Node 1 Sub 1'
    $N1.Nodes.Add($newNode)
    
    $newNode = New-Object System.Windows.Forms.TreeNode  
    $newNode.Name = 'Node 1 Sub 2'
    $newNode.Text = 'Node 1 Sub 2'
    $N1.Nodes.Add($newNode) | Out-Null
    # There can be deeper levels of treenodes
    
    $TV_AfterCheck = {
        if($_.Node.Checked) {
            #[System.Windows.Forms.MessageBox]::Show('Node ' + $_.Node.Text + ' checked')
        }
        else {
            #[System.Windows.Forms.MessageBox]::Show('Node ' + $_.Node.Text + ' unchecked')
        }
    }
    
    $treeView.Add_AfterCheck($TV_AfterCheck)
    $form.Controls.Add($treeView)
    $form.ShowDialog()
    

    我找到的解决方案是针对另一种语言量身定制的,我无法在PowerShell中使用它。有关于这个主题的很多信息,但它在其他编程语言中都有。

    另一种语言的解决方案:

    Private Sub CheckChildNode(ByVal currNode As TreeNode)
    'set the children check status to the same as the current node
    Dim checkStatus As Boolean = currNode.Checked
    For Each node As TreeNode In currNode.Nodes
    node.Checked = checkStatus
    CheckChildNode(node)
    Next
    End Sub
    
    Private Sub CheckParentNode(ByVal currNode As TreeNode)
    Dim parentNode As TreeNode = currNode.Parent
    If parentNode Is Nothing Then Exit Sub
    parentNode.Checked = True
    For Each node As TreeNode In parentNode.Nodes
    If Not node.Checked Then
    parentNode.Checked = False
    Exit For
    End If
    Next
    CheckParentNode(parentNode)
    End Sub
    
    Private Sub treeview_AfterCheck(ByVal sender As System.Object, ByVal e As
    System.Windows.Forms.TreeViewEventArgs) Handles treeview.AfterCheck
    RemoveHandler treeview.AfterCheck, AddressOf treeview_AfterCheck
    CheckChildNode(e.Node)
    CheckParentNode(e.Node)
    AddHandler treeview.AfterCheck, AddressOf treeview_AfterCheck
    End Sub
    

    如果有人可以帮助我将它粘贴在一起真的很棒,那么它可以在PowerShell中使用。谢谢你的帮助。

1 个答案:

答案 0 :(得分:3)

下面基本上是对你包含的VB.NET代码的重写:

您需要包含以下功能:

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
 foreach ($n in $parent.nodes) {
    if(!$n.checked) {
      $parent.checked = $false
      break
    }  
  }
  checkparentNode($parent)
}

将您的事件处理程序更改为:

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

这将为您提供您所追求的行为。