如何在PowerShell Windows Forms中实现NPS单选评分及事件处理
修复后的PowerShell NPS评分界面代码
Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName System.Drawing $form = [System.Windows.Forms.Form]::new() $form.Text = 'NPS-Test' $form.MaximizeBox = $false $form.MinimizeBox = $false $form.Size = @{Width=410;Height=140} $form.StartPosition = 'CenterScreen' $form.FormBorderStyle = 'Fixed3D' # 声明脚本级变量,保存选中的NPS评分值 $script:selectedNpsValue = $null function add-FormControl($parent, $type, $x, $y, $width, $height, $text, $font) { $c = new-object System.Windows.Forms.$type $c.Location = @{x=$x; y=$y} $c.Size = @{Width=$width;Height=$height} $c.Text = $text if ($font) { $c.Font = $font } $parent.Controls.Add($c) return $c } $nps = [object[]]::new(11) foreach($i in 0..10) { $nps[$i] = add-FormControl $form 'Checkbox' (10+35*$i) 20 30 30 $i $nps[$i].TextAlign = 'MiddleCenter' $nps[$i].Appearance = 'button' # 绑定点击事件 $nps[$i].Add_Click({ # 获取当前点击的控件,对应其他语言中的this $currentBtn = $sender # 遍历所有NPS按钮,实现单选互斥效果 foreach ($btn in $nps) { $btn.Checked = ($btn -eq $currentBtn) } # 更新选中的评分值 $script:selectedNpsValue = [int]$currentBtn.Text }) # 设置NPS分段颜色 if ($i -gt 8) { $nps[$i].BackColor = 'PaleGreen' } elseif ($i -gt 6) { $nps[$i].BackColor = 'Yellow' } else { $nps[$i].BackColor = 'OrangeRed' } } $ok = add-FormControl $form 'Button' 170 70 60 20 'OK' $ok.DialogResult = 'OK' $form.TopMost = $true $result = $form.ShowDialog() # 处理OK按钮返回的结果 if ($result -eq [System.Windows.Forms.DialogResult]::OK -and $script:selectedNpsValue -ne $null) { [System.Windows.Forms.MessageBox]::Show("您选中的NPS评分为:$script:selectedNpsValue", "结果") # 也可以直接将$script:selectedNpsValue用于后续逻辑 }
关键修复说明
- 当前控件获取:在PowerShell的WinForms事件脚本块中,
$sender就是触发事件的当前控件,等价于其他语言里的this,可以直接用来获取按钮的文本、状态等属性。 - 单选互斥逻辑:点击任意评分按钮时,遍历所有NPS按钮,将除当前按钮外的其他按钮设为未选中状态,实现类似单选按钮的互斥选择效果。
- 变量作用域处理:用
$script:前缀声明全局脚本变量selectedNpsValue,确保事件脚本块能修改并传递选中的值,避免局部作用域导致的值丢失问题。 - 闭包问题解决:原代码直接引用循环变量
$i会导致所有事件都绑定最后一次循环的i值,改用$sender.Text获取当前按钮的评分值,彻底解决闭包陷阱。
内容的提问来源于stack exchange,提问作者Carsten
相关产品推荐
相关产品推荐

