PowerShell .NET Mimic Windows 树节点的默认复选框行为
PowerShell .NET Mimic Windows default checkbox behaviour for treenodes
在我们的 Windows.Forms
表单中,我们试图实现以下目标:
- Check/uncheck当你check/uncheck一个父节点时的所有子节点。
- 如果检查了所有子节点,则自动检查父节点。
- 如果其中一个子节点未选中,则自动取消选中父节点。
测试代码:
$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)
}
这将为您提供所需的行为。
在我们的 Windows.Forms
表单中,我们试图实现以下目标:
- Check/uncheck当你check/uncheck一个父节点时的所有子节点。
- 如果检查了所有子节点,则自动检查父节点。
- 如果其中一个子节点未选中,则自动取消选中父节点。
测试代码:
$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)
}
这将为您提供所需的行为。