You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell WinForms:事件块内ListBox的SelectedItems值获取方法

问题:WinForms ListBox选中项无法获取,始终为Null

从下拉列表$RCVROption选择选项后,再选择$listBox中的选项,$listBox.SelectedItems的值始终为Null,如何获取该值并赋值给变量$x?
目标是将$listBox.SelectedItems的文本作为文件名,选中列表选项并点击OK后运行对应文件。尝试的脚本如下:

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
[System.Windows.Forms.Application]::EnableVisualStyles()

 
$form = New-Object System.Windows.Forms.Form
$form.Text = 'DMP Receiver Tail'
$form.Size = New-Object System.Drawing.Size(400,300)
$form.StartPosition = 'CenterScreen'
 
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Point(115,220)
$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(190,220)
$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(60,20)
$label.Size = New-Object System.Drawing.Size(280,20)
$label.Text = 'Which Receiver Would You Like To Tail?:'
$form.Controls.Add($label)
 
$RCVROption = new-object System.Windows.Forms.combobox
$RCVROption.Location = new-object System.Drawing.Size(20,40)
$RCVROption.Size = new-object System.Drawing.Size(335,30)
[void] $RCVROption.Items.Add('Receiver 560')
[void] $RCVROption.Items.Add('Receiver 2560')
$RCVROption.tabIndex = '0'
$RCVROption.DropDownStyle = [System.Windows.Forms.ComboBoxStyle]::DropDownList;
 $RCVROption.add_SelectedValueChanged(
 {
    
 if($RCVROption.SelectedItem -eq 'Receiver 560')
 {

$listBox = New-Object System.Windows.Forms.Listbox
$listBox.Location = New-Object System.Drawing.Point(40,100)
$listBox.Size = New-Object System.Drawing.Size(260,80)
 
$listBox.SelectionMode = 'MultiExtended'
 
[void] $listBox.Items.Add('DMP-560-Line1')
[void] $listBox.Items.Add('DMP-560-Line2')
[void] $listBox.Items.Add('DMP-560-Line3')
[void] $listBox.Items.Add('DMP-560-Line4')
[void] $listBox.Items.Add('DMP-560-Line5')
$form.Controls.Add($listBox)
} 

ELSEIF($RCVROption.SelectedItem -eq 'Receiver 2560')
{
$listBox = New-Object System.Windows.Forms.Listbox
$listBox.Location = New-Object System.Drawing.Point(40,100)
$listBox.Size = New-Object System.Drawing.Size(260,80)
 
$listBox.SelectionMode = 'MultiExtended'
 
[void] $listBox.Items.Add('DMP-2560-Line1')
[void] $listBox.Items.Add('DMP-2560-Line2')
[void] $listBox.Items.Add('DMP-2560-Line3')
[void] $listBox.Items.Add('DMP-2560-Line4')
[void] $listBox.Items.Add('DMP-2560-Line5')
$form.Controls.Add($listBox)
}
}
)
$form.Controls.Add($RCVROption)
$form.Topmost = $true
$result = $form.ShowDialog()
 

 
if ($result -eq [System.Windows.Forms.DialogResult]::OK)
{
   $x = $listBox.SelectedItems
    $Fpath = 'D:\Toolbar\On Call\DMP-Tail\' + $x + '.exe'
    Start-process -filepath $FPath
     $Fpath
} 

问题根源

  1. 作用域限制:事件脚本块内创建的$listBox是局部变量,外部的OK按钮逻辑无法访问该变量,导致$listBox在OK块中为Null。
  2. 重复创建控件:每次切换ComboBox选项都会新建ListBox并添加到窗体,造成控件叠加,且只有最后创建的ListBox在局部作用域中,进一步引发变量访问问题。

修复方案与修正代码

  1. 提前声明脚本级ListBox:在事件外部创建ListBox并添加到窗体,确保变量在整个脚本作用域中可访问。
  2. 动态更新ListBox内容:切换ComboBox选项时清空现有项并添加对应内容,避免重复创建控件。
  3. 处理多选场景:由于ListBox设置了MultiExtended多选模式,需遍历选中项逐个启动程序。

修正后的脚本:

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
[System.Windows.Forms.Application]::EnableVisualStyles()

$form = New-Object System.Windows.Forms.Form
$form.Text = 'DMP Receiver Tail'
$form.Size = New-Object System.Drawing.Size(400,300)
$form.StartPosition = 'CenterScreen'

$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Point(115,220)
$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(190,220)
$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(60,20)
$label.Size = New-Object System.Drawing.Size(280,20)
$label.Text = 'Which Receiver Would You Like To Tail?:'
$form.Controls.Add($label)

$RCVROption = New-Object System.Windows.Forms.ComboBox
$RCVROption.Location = New-Object System.Drawing.Size(20,40)
$RCVROption.Size = New-Object System.Drawing.Size(335,30)
[void]$RCVROption.Items.Add('Receiver 560')
[void]$RCVROption.Items.Add('Receiver 2560')
$RCVROption.TabIndex = 0
$RCVROption.DropDownStyle = [System.Windows.Forms.ComboBoxStyle]::DropDownList

# 提前创建ListBox并添加到窗体,脚本级变量全局可访问
$listBox = New-Object System.Windows.Forms.ListBox
$listBox.Location = New-Object System.Drawing.Point(40,100)
$listBox.Size = New-Object System.Drawing.Size(260,80)
$listBox.SelectionMode = 'MultiExtended'
$form.Controls.Add($listBox)

$RCVROption.add_SelectedValueChanged({
    $listBox.Items.Clear() # 清空现有项
    switch ($RCVROption.SelectedItem) {
        'Receiver 560' {
            [void]$listBox.Items.Add('DMP-560-Line1')
            [void]$listBox.Items.Add('DMP-560-Line2')
            [void]$listBox.Items.Add('DMP-560-Line3')
            [void]$listBox.Items.Add('DMP-560-Line4')
            [void]$listBox.Items.Add('DMP-560-Line5')
        }
        'Receiver 2560' {
            [void]$listBox.Items.Add('DMP-2560-Line1')
            [void]$listBox.Items.Add('DMP-2560-Line2')
            [void]$listBox.Items.Add('DMP-2560-Line3')
            [void]$listBox.Items.Add('DMP-2560-Line4')
            [void]$listBox.Items.Add('DMP-2560-Line5')
        }
    }
})

$form.Controls.Add($RCVROption)
$form.Topmost = $true
$result = $form.ShowDialog()

if ($result -eq [System.Windows.Forms.DialogResult]::OK) {
    # 遍历所有选中项,逐个启动对应程序
    foreach ($selectedItem in $listBox.SelectedItems) {
        $Fpath = "D:\Toolbar\On Call\DMP-Tail\$selectedItem.exe"
        Start-Process -FilePath $FPath
        Write-Host "已启动程序: $Fpath"
    }
}

内容的提问来源于stack exchange,提问作者Zagnut119

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 23:50:23