Powershell Winforms GUI - 在 CheckedListBox 中,防止用户取消选中所有复选框并在事件处理程序中保留“在任何时候仅保留 1 个复选框”

问题描述 投票:0回答:1

我对 powershell winforms 很陌生,如果这是一个基本问题,我很抱歉......

基本上是标题...我有一个蹩脚的 GUI 表单(是的,我知道我应该使用径向按钮,请不要建议更改它)。

我希望用户只能在任何一个时间点选中一个复选框,并且我从不希望他们能够取消选中所有复选框..此时,如果他们单击选项 1,那么此时选项 1 已经被选中,它将成功地允许他们取消选中选项 1,然后不会检查任何内容,并且用户已设法自己完成 f#$^(因为他们似乎总是设法找到一种方法)。

请帮忙:(

我的理解是我需要修改 $checkListBox.add_ItemCheck 事件处理程序,但我无法在保留现有行为的同时思考如何做到这一点。

Add-Type -AssemblyName System.Windows.Forms

$form = New-Object System.Windows.Forms.Form
$form.Size = New-Object System.Drawing.Size(300, 200)

$checkListBox = New-Object System.Windows.Forms.CheckedListBox
$checkListBox.Location = New-Object System.Drawing.Point(10, 10)
$checkListBox.Size = New-Object System.Drawing.Size(200, 150)

# Add items to the checkListBox
$checkListBox.Items.Add("Option 1") | Out-Null
$checkListBox.Items.Add("Option 2") | Out-Null
$checkListBox.Items.Add("Option 3") | Out-Null
$checkListBox.SelectionMode = 'One'
$checkListBox.CheckOnClick = $true
$checkListBox.SetItemChecked(0, $true) # set the first item by default.

# Add ItemCheck event handler
$checkListBox.add_ItemCheck({
    param($sender, $e)
    foreach ($index in $checkListBox.CheckedIndices) {
        if ($index -ne $e.Index) {
            $checkListBox.SetItemChecked($index, $false)
        }
    }
})

$form.Controls.Add($checkListBox)

$form.ShowDialog() | Out-Null

在下面尝试了这个......它似乎有效:) ..但不完全确定这是否是正确/安全的做事方式:

Add-Type -AssemblyName System.Windows.Forms

$form = New-Object System.Windows.Forms.Form
$form.Size = New-Object System.Drawing.Size(300, 200)

$checkListBox = New-Object System.Windows.Forms.CheckedListBox
$checkListBox.Location = New-Object System.Drawing.Point(10, 10)
$checkListBox.Size = New-Object System.Drawing.Size(200, 150)
("Option 1","Option 2","Option 3") | % {$checkListBox.Items.Add("$_") | Out-Null}
$checkListBox.SelectionMode = 'One'
$checkListBox.CheckOnClick = $true
$checkListBox.SetItemChecked(0, $true) # set the first item by default.

$handlingEvent = $false

$checkListBox.add_ItemCheck({
    param($sender, $e)
    if ($handlingEvent) { return }
    $handlingEvent = $true
    try {
        $currentCheckedState = [System.Windows.Forms.CheckState]::Unchecked
        $newCheckedState = [System.Windows.Forms.CheckState]::Unchecked
        if ($e.CurrentValue -eq 1) { $currentCheckedState = [System.Windows.Forms.CheckState]::Checked }
        if ($e.NewValue -eq 1) { $newCheckedState = [System.Windows.Forms.CheckState]::Checked }
        if ($currentCheckedState -eq [System.Windows.Forms.CheckState]::Checked -and $newCheckedState -eq [System.Windows.Forms.CheckState]::Unchecked) { $e.NewValue = [System.Windows.Forms.CheckState]::Checked }
        $checkListBox.CheckedIndices | ForEach-Object { if ($_ -ne $e.Index) { $checkListBox.SetItemChecked($_, $false) } }
    } finally { $handlingEvent = $false }
})

$form.Controls.Add($checkListBox)

# Show the form, but since we only seem to get "cancel" in the resultant object, no point keeping it. we only care what checkbox they selected..
$form.ShowDialog() | out-null

# Output the result
$DialogOut = $checkListBox.CheckedItems
Write-host "User Selected: $DialogOut"
powershell winforms checkedlistbox
1个回答
0
投票

这似乎已经解决了,谢谢@mclayton!

$form = New-Object System.Windows.Forms.Form
$form.Size = New-Object System.Drawing.Size(300, 200)

$checkListBox = New-Object System.Windows.Forms.CheckedListBox
$checkListBox.Location = New-Object System.Drawing.Point(10, 10)
$checkListBox.Size = New-Object System.Drawing.Size(200, 150)
("Option 1","Option 2","Option 3") | % {$checkListBox.Items.Add("$_") | Out-Null}
$checkListBox.SelectionMode = 'One'
$checkListBox.CheckOnClick = $true
$checkListBox.SetItemChecked(0, $true) # set the first item by default.

$handlingEvent = $false

$checkListBox.add_ItemCheck({
    param($sender, $e)
    if ($handlingEvent) { return }
    $handlingEvent = $true
    try {
        $currentCheckedState = [System.Windows.Forms.CheckState]::Unchecked
        $newCheckedState = [System.Windows.Forms.CheckState]::Unchecked
        if ($e.CurrentValue -eq 1) { $currentCheckedState = [System.Windows.Forms.CheckState]::Checked }
        if ($e.NewValue -eq 1) { $newCheckedState = [System.Windows.Forms.CheckState]::Checked }
        if ($currentCheckedState -eq [System.Windows.Forms.CheckState]::Checked -and $newCheckedState -eq [System.Windows.Forms.CheckState]::Unchecked) { $e.NewValue = [System.Windows.Forms.CheckState]::Checked }
        $checkListBox.CheckedIndices | ForEach-Object { if ($_ -ne $e.Index) { $checkListBox.SetItemChecked($_, $false) } }
    } finally { $handlingEvent = $false }
})

$form.Controls.Add($checkListBox)

# Show the form, but since we only seem to get "cancel" in the resultant object, no point keeping it. we only care what checkbox they selected..
$form.ShowDialog() | out-null

# Output the result
$DialogOut = $checkListBox.CheckedItems
Write-host "User Selected: $DialogOut"
© www.soinside.com 2019 - 2024. All rights reserved.