.net - PowerShell .NET 模仿 Windows 树节点的默认复选框行为

标签 .net winforms forms powershell

在我们的 Windows.Forms 表单中,我们试图实现以下目标:

  1. 在选中/取消选中父节点时选中/取消选中所有子节点。
  2. 如果检查了所有子节点,则自动检查父节点。
  3. 如果未选中某个子节点,则自动取消选中父节点。

测试代码:

$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 中运行,那就太好了。感谢您的帮助。

最佳答案

下面基本上是您所包含的 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)
}

这会给你你想要的行为。

关于.net - PowerShell .NET 模仿 Windows 树节点的默认复选框行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27900278/

相关文章:

c# - 超过 SMTP 限制发送电子邮件

c# - 尝试重建Windows窗体的解决方案时出错

javascript - 输入文本更改时提交表单

javascript - angularjs 表单验证显示页面加载成功

c# - 从 raven db 文档存储加载对象时如何防止属性被序列化

.net - 有人知道可能存在的任何 .NET OpenID Provider 示例代码吗?

.net - Math.NET 可以解决任何矩阵吗?

c# - 获取被点击按钮的文本值

.net - 可折叠侧面板控制

当用户点击 Enter 时,Javascript 登录表单不提交