0

I've started with powershell forms and this is my first attempt.

I'd like to add more checkboxes and I've no problem with "CheckStateChanged". I'm looking for an alternative code with foreach declaration. How can I shorten the code with my checkboxes using foreach x in y?

My first attempt works well:

$CheckBox1.Add_CheckStateChanged({
if ($CheckBox1.Checked){$CheckBox2.Enabled = $false} else {$CheckBox2.Enabled = $true}
if ($CheckBox1.Checked){$CheckBox3.Enabled = $false} else {$CheckBox3.Enabled = $true}
if ($CheckBox1.Checked){$CheckBox4.Enabled = $false} else {$CheckBox4.Enabled = $true}
})

$CheckBox2.Add_CheckStateChanged({
if ($CheckBox2.Checked){$CheckBox1.Enabled = $false} else {$CheckBox1.Enabled = $true}
if ($CheckBox2.Checked){$CheckBox3.Enabled = $false} else {$CheckBox3.Enabled = $true}
if ($CheckBox2.Checked){$CheckBox4.Enabled = $false} else {$CheckBox4.Enabled = $true}
})

$CheckBox3.Add_CheckStateChanged({
if ($CheckBox3.Checked){$CheckBox1.Enabled = $false} else {$CheckBox1.Enabled = $true}
if ($CheckBox3.Checked){$CheckBox2.Enabled = $false} else {$CheckBox2.Enabled = $true}
if ($CheckBox3.Checked){$CheckBox4.Enabled = $false} else {$CheckBox4.Enabled = $true}
})

$CheckBox4.Add_CheckStateChanged({
if ($CheckBox4.Checked){$CheckBox1.Enabled = $false} else {$CheckBox1.Enabled = $true}
if ($CheckBox4.Checked){$CheckBox2.Enabled = $false} else {$CheckBox2.Enabled = $true}
if ($CheckBox4.Checked){$CheckBox3.Enabled = $false} else {$CheckBox3.Enabled = $true}
})

An alternative I'm looking for might look like:

CheckBox1.Add_CheckStateChanged({ if (CheckBox1.Checked){foreach CheckBox in $_.Enabled = $false} else {$CheckBox2.Enabled = true}

Unfortunately I can't figure it out how to use a foreach function with checkboxes. I'd like to add more than ten checkboxes to my form.

7
  • You mention "a problem with CheckStateChanged". It's not clear whether something isn't working or if you just want shorter code. If you're encountering an error or the code isn't doing what you expect please edit the question to add those details. Commented May 27, 2019 at 11:13
  • Thank you for you hint, I've updated my thread. Commented May 27, 2019 at 11:26
  • Code Review is focused on improving working code, so you might get better answers from there. Commented May 27, 2019 at 11:32
  • You might find the Switch commandlet useful: learn.microsoft.com/en-us/powershell/module/… Commented May 27, 2019 at 11:38
  • 2
    Have you considered using a radio button group (since your check boxes are all mutually exclusive anyways)? Commented May 27, 2019 at 11:50

1 Answer 1

1

I agree with Mathias R. Jessen that I too think you are better off using a radio button group.

However, if you want to have mutually exclusive checkboxes and shorten your code, you could do this:

# create a scriptblock to be used in every checkboxes CheckStateChanged event
$checkChange = {
    # loop through all the forms checkbox controls.
    # the sender object is captured in the automatic variable '$this'
    $form.Controls | Where-Object {$_ -is [System.Windows.Forms.Checkbox]} | ForEach-Object {
        # if this checkbox is checked, disable all others, otherwise
        # set all checkbox controls to Enabled
        $_.Enabled = if ($this.Checked) { ($_ -eq $this) } else { $true }
    }
}

# add the scriptblock to the individual checkbox objects
$CheckBox1.Add_CheckStateChanged($checkChange)
$CheckBox2.Add_CheckStateChanged($checkChange)
$CheckBox3.Add_CheckStateChanged($checkChange)
$CheckBox4.Add_CheckStateChanged($checkChange)


As per your comment, yes, it is possible to collect all checkbox controls in an array and use that to build the form. It may shorten your code, but makes it less readable at the same time. Here's an example:

$chkBoxes = @()
for ($i = 0; $i -lt 4; $i++) {
    $dummy = New-Object System.Windows.Forms.Checkbox
    $dummy.Location = New-Object System.Drawing.Size(10,(20 + $i * 20))
    # add more COMMON properties if need be.
    # individual properties need to be set on each box by index.
    # e.g. $chkBoxes[0].Cursor = [System.Windows.Forms.Cursors]::Hand

    # set the CheckStateChanged handler on the control
    $dummy.Add_CheckStateChanged($checkChange)
    # add the new control to the $chkBoxes array
    $chkBoxes += $dummy
}
# add the array of controls to the form
$form.Controls.AddRange($chkBoxes)

Hope that helps

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you very much for this snippet. It's exactly what I've been looking for. I've started with a basic form, I'm a pure beginner. This is a fantastic example:)
If this route is taken, would a next step be to put all buttons in an array?
Thank you very much for your second example. I prefer your first example because it's easier to understand for a beginner like me. I'll keep your second example in mind, it's a little bit too complicated for me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.