我想知道如何在选择所有子节点时检索父节点的名称。在下面的代码中,函数Get-CheckedNodes
检索前面带有复选标记的所有内容。
在下面的示例中,如果您选择'Cars>蓝色'它将回归:兰博基尼,玛莎拉蒂和蓝色。这是正确的,但我只想让它报告父'Blue',因为一切都被选中了。但是,当只有一辆车被选中时,它应该只报告那辆车,而不是它的父母。
代码:
Function Add-Node($Nodes, $Path) {
$Path.Split("/") | % {
Write-Verbose "Searching For: $_"
$SearchResult = $Nodes.Find($_, $False)
If ($SearchResult.Count -eq 1) {
Write-Verbose "Selecting: $($SearchResult.Name)"
$Nodes = $SearchResult[0].Nodes
}
Else {
Write-Verbose "Adding: $_"
$Node = New-Object Windows.Forms.TreeNode($_)
$Node.Name = $_
$Nodes.Add($Node) | Out-Null
}
}
}
Function Get-CheckedNodes($nodes) {
foreach ($n in $Nodes) {
if ($n.nodes.count -gt 0) {
Get-CheckedNodes $n.nodes
}
if ($n.checked) {
Write-Output $n.Name
}
}
}
Function Select-ChildNodes($node) {
$checkStatus = $node.Checked
foreach ($n in $node.Nodes) {
$n.checked = $checkstatus
Select-ChildNodes($n)
}
}
Function Select-ParentNode($node) {
$parent = $node.Parent
if($parent -eq $null) {
return
}
$parent.checked = $true
foreach ($n in $parent.Nodes) {
if(!$n.checked) {
$parent.Checked = $false
break
}
}
Select-ParentNode($parent)
}
$script:SelectedOU = $null
Add-Type -AssemblyName System.Windows.Forms
$Form = New-Object System.Windows.Forms.Form
$Form.ClientSize = '342, 502'
$Form.FormBorderStyle = 'FixedDialog'
$ButtonOK_Click = {
if ($script:SelectedOU = Get-CheckedNodes $treeView.Nodes) {
$Form.close()
}
elseif (([System.Windows.Forms.MessageBox]::Show(
"You haven't selected anything.`nAre you sure you want to leave?",
"Oops!",'YesNo','Information')) -eq 'Yes') {$Form.close()}
}
$Treeview_AfterCheck = {
$Treeview.Remove_AfterCheck($Treeview_AfterCheck)
Select-ChildNodes($_.node)
Select-ParentNode($_.node)
$Treeview.Add_AfterCheck($Treeview_AfterCheck)
}
$TreeView = New-Object System.Windows.Forms.TreeView
$TreeView.Dock = 'Fill'
$TreeView.CheckBoxes = $true
$Treeview.Add_AfterCheck($Treeview_AfterCheck)
Add-Node $TreeView.Nodes "Fruits"
Add-Node $TreeView.Nodes "Vegetables"
Add-Node $TreeView.Nodes "Cars"
Add-Node $TreeView.Nodes "Cars/Blue"
Add-Node $TreeView.Nodes "Cars/Blue/Lamborghini"
Add-Node $TreeView.Nodes "Cars/Blue/Maserati"
Add-Node $TreeView.Nodes "Cars/Red"
Add-Node $TreeView.Nodes "Cars/Red/Lamborghini"
Add-Node $TreeView.Nodes "Cars/Red/Maserati"
$ButtonCancel = New-Object System.Windows.Forms.Button
$ButtonCancel.text = “&Cancel”
$ButtonCancel.Location = '120,467'
$ButtonCancel.size = '75,23'
$ButtonCancel.Anchor = 'Bottom, Left'
$ButtonCancel.add_Click({$Form.close()})
$Form.Controls.Add($ButtonCancel)
$ButtonOK = New-Object System.Windows.Forms.Button
$ButtonOK.Location = '245,467'
$ButtonOK.Size = '75,23'
$ButtonOK.Name = 'ButtonOK'
$ButtonOK.Text = 'OK'
$ButtonOK.add_Click($ButtonOK_Click)
$Form.Controls.Add($ButtonOK)
$Form.Controls.Add($TreeView)
$Form.ShowDialog() > $null
$script:SelectedOU
感谢您的帮助。
答案 0 :(得分:1)
一种方法是在编写节点文本之前添加一个额外的检查,查找当前级别未检查的内容,这只发生在Get-CheckedNodes函数中。
因此,如果未检查当前级别中的至少一个节点,则将检查的节点写入输出,否则不执行任何操作。并且,如果在当前级别检查所有节点,则将检查父级,并将其文本写入输出。此外,如果检查节点,则其所有子节点都将是。所以这应该适用于所有情况。
Function Get-CheckedNodes($nodes) {
$allChecked = $true
foreach ($n in $Nodes)
{
if (!$n.checked) {
$allChecked = $false
break
}
}
foreach ($n in $Nodes)
{
if ($n.nodes.count -gt 0) {
Get-CheckedNodes $n.nodes
}
if ($n.checked -and $allChecked -eq $false) {
Write-Output $n.Name
}
}
}