PowerShell中ListBox关联显示名与计算机名:用数组还是集合?
实现ListBox显示名与计算机名的关联
当然可以实现显示名和计算机名的关联!数组是一种可行的方法,但Windows Forms的ListBox本身就提供了更灵活的方式来存储额外数据,我给你几种实用方案:
方案1:用自定义对象(推荐)
这是最清晰、易维护的方式——创建包含显示名和计算机名的自定义对象,让ListBox显示友好名称,同时存储完整对象。选中项时直接提取计算机名即可:
Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName System.Drawing # 定义计算机列表:包含友好显示名和实际计算机名 $computers = @( [PSCustomObject]@{ DisplayName = 'Screen in building 1 first floor' ComputerName = 'PC-B1-01' }, [PSCustomObject]@{ DisplayName = 'Screen in building 1 second floor' ComputerName = 'PC-B1-02' }, [PSCustomObject]@{ DisplayName = 'Screen in building 2 4th floor' ComputerName = 'PC-B2-04' }, [PSCustomObject]@{ DisplayName = 'Screen in building 3 basement' ComputerName = 'PC-B3-B01' } ) $form = New-Object System.Windows.Forms.Form $form.Text = 'Select a Computer' $form.Size = New-Object System.Drawing.Size(300,200) $form.StartPosition = 'CenterScreen' $OKButton = New-Object System.Windows.Forms.Button $OKButton.Location = New-Object System.Drawing.Point(75,120) $OKButton.Size = New-Object System.Drawing.Size(75,23) $OKButton.Text = 'OK' $OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK $form.AcceptButton = $OKButton $form.Controls.Add($OKButton) $CancelButton = New-Object System.Windows.Forms.Button $CancelButton.Location = New-Object System.Drawing.Point(150,120) $CancelButton.Size = New-Object System.Drawing.Size(75,23) $CancelButton.Text = 'Cancel' $CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel $form.CancelButton = $CancelButton $form.Controls.Add($CancelButton) $label = New-Object System.Windows.Forms.Label $label.Location = New-Object System.Drawing.Point(10,20) $label.Size = New-Object System.Drawing.Size(280,20) $label.Text = 'Please select a computer:' $form.Controls.Add($label) $listBox = New-Object System.Windows.Forms.ListBox $listBox.Location = New-Object System.Drawing.Point(10,40) $listBox.Size = New-Object System.Drawing.Size(260,20) $listBox.Height = 80 # 关键设置:指定ListBox显示对象的DisplayName属性 $listBox.DisplayMember = 'DisplayName' # 绑定数据源为自定义对象数组 $listBox.DataSource = $computers $form.Controls.Add($listBox) $form.Topmost = $true $result = $form.ShowDialog() if ($result -eq [System.Windows.Forms.DialogResult]::OK) { $selectedComputer = $listBox.SelectedItem $c = Get-Credential Domain\Username # 直接提取对象的ComputerName属性 Restart-Computer -ComputerName $selectedComputer.ComputerName -Credential $c -Force Write-Host "Restarting: $($selectedComputer.DisplayName) ($($selectedComputer.ComputerName))" }
这种方法的优势是:显示名和计算机名绑定在一起,不会因为顺序调整出错,后期维护也更直观。
方案2:用数组索引关联
如果你偏爱简单的数组方式,可以创建两个对应顺序的数组——一个存显示名,一个存计算机名,通过选中项的索引来匹配:
# 定义对应顺序的数组 $displayNames = @( 'Screen in building 1 first floor', 'Screen in building 1 second floor', 'Screen in building 2 4th floor', 'Screen in building 3 basement' ) $computerNames = @( 'PC-B1-01', 'PC-B1-02', 'PC-B2-04', 'PC-B3-B01' ) # 向ListBox添加显示名 foreach ($name in $displayNames) { [void]$listBox.Items.Add($name) } # 选中后的处理 if ($result -eq [System.Windows.Forms.DialogResult]::OK) { $selectedIndex = $listBox.SelectedIndex $targetComputer = $computerNames[$selectedIndex] $c = Get-Credential Domain\Username Restart-Computer -ComputerName $targetComputer -Credential $c -Force }
⚠️ 注意:这种方式必须严格保证两个数组的顺序完全对应,否则会出现匹配错误,适合简单且不会频繁修改的场景。
方案3:用ListBoxItem的Tag属性
你也可以给每个ListBox项单独设置Tag属性,把计算机名存在这个属性里:
# 添加项时设置Tag $item1 = New-Object System.Windows.Forms.ListBoxItem('Screen in building 1 first floor') $item1.Tag = 'PC-B1-01' [void]$listBox.Items.Add($item1) $item2 = New-Object System.Windows.Forms.ListBoxItem('Screen in building 1 second floor') $item2.Tag = 'PC-B1-02' [void]$listBox.Items.Add($item2) # 选中后的处理 if ($result -eq [System.Windows.Forms.DialogResult]::OK) { $targetComputer = $listBox.SelectedItem.Tag $c = Get-Credential Domain\Username Restart-Computer -ComputerName $targetComputer -Credential $c -Force }
这种方式适合单个项需要存储额外数据的场景,操作也比较直接。
内容的提问来源于stack exchange,提问作者Matt Williamson
相关产品推荐
相关产品推荐

