I'm very new to powershell winforms, apologies if this is a basic question...
Basically the title... i have a crappy GUI form (and yes i know i should probably use a radial button, please don't suggest changing that).
I want the user to ONLY be able to check a single checkbox at any one point in time, and i never want them to be able to uncheck all checkboxes.. at the moment if they click on Option 1, when it is already checked, it will successfully allow them to uncheck Option 1 and then nothing is checked and the user has managed to f#$^ themselves (as they always seem to manage to find a way to do).
Please help :(
My understanding is i need to modify the $checkListBox.add_ItemCheck event handler, but i can't wrap my brain around how i would do that, whilst retaining the existing behaviour.
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
Tried this below...and it seems to work :) .. Not entirely sure if it is the correct/safe way of doing things however:
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"
This seems to have sorted it, thanks @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"