0

I created an array of Check boxes. I could create a event handler for each check box separately but as it would be lengthy code I thought if I could create them using loop. When event handler is written inside loop the event is being handled but the result shown is wrong i.e -> when I select i'th check box the event is handled but $checkBox_Charts[$i].Checked is always returning False whether the box is checked or unchecked.

Edit 1:

  • I realized even when checked event is raised on any check box this code is returning checked status of last element in for loop,
  • Adding the complete code

Code:

function whichCharts(){
    Write-Host "CP1: in whichCharts"
    foreach ($key_chart in $charts.Keys){
        Write-Host $charts[$key_chart]
    }
}

function checkbox_test{
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")

# Set the size of your form
$Form = New-Object System.Windows.Forms.Form
$Form.width = 1000
$Form.height = 600
$Form.Text = ”My First Form with a working checkbox”

# Set the font of the text to be used within the form
$Font = New-Object System.Drawing.Font("Times New Roman",12)
$Form.Font = $Font



$charts = @("x","y","z")

$checkBox_Charts =[System.Windows.Forms.checkbox[]]::new(3)

$index_checkBox_Charts=0
for ($i=0;$i -lt $charts.Count; $i++){
$CheckBox = new-object System.Windows.Forms.checkbox
    $height = (60*$i)+20
    $CheckBox.Location = new-object System.Drawing.Size(100,$height)
$CheckBox.Size = '150,50'
$CheckBox.Text = $charts[$i]
$CheckBox.Checked = $false
$checkBox_Charts[$i] = $CheckBox

}



# Add an OK button
$OKButton = new-object System.Windows.Forms.Button
$OKButton.Location = '50,500'
$OKButton.Size = '100,40'
$OKButton.Text = "OK"
$OKButton.DialogResult=[System.Windows.Forms.DialogResult]::OK

#Add a cancel button
$CancelButton = new-object System.Windows.Forms.Button
$CancelButton.Location = '255,100'
$CancelButton.Size = '100,40'
$CancelButton.Text = "Cancel"
$CancelButton.DialogResult=[System.Windows.Forms.DialogResult]::Cancel

# Create a group that will contain your radio buttons
$MyGroupBox = New-Object System.Windows.Forms.GroupBox
$MyGroupBox.Location = '40,30'
$MyGroupBox.size = '800,400'
$MyGroupBox.text = "Do you like Cheese?"

# Add all the GroupBox controls on one line
$MyGroupBox.Controls.AddRange(@($checkBox_Charts))

$Form.Controls.AddRange(@($MyGroupBox,$OKButton,$CancelButton))
###########  This is the important piece ##############
#                                                     #
# Do something when the state of the checkbox changes #
#######################################################

for($i=0; $i -lt 2; $i++){
    $checkBox_Charts[$i].Add_CheckStateChanged({
    Write-Host "CP2: in Add_CheckStateChanged " + $checkBox_Charts[$i].Checked
    Write-Host $checkBox_Charts[$i]
    Write-Host $i})

}



# Activate the form
$Form.Add_Shown({$Form.Activate()})
[void] $Form.ShowDialog() 
}



#Call the function
checkbox_test
4
  • Can you give me some test data to fill this with? Commented Apr 4, 2020 at 18:18
  • Code sample is incomplete, where is $charts defined? Commented Apr 4, 2020 at 19:21
  • yes charts is defined Commented Apr 4, 2020 at 19:33
  • @ArcSet I have added complete code, please check on it. Commented Apr 5, 2020 at 8:05

1 Answer 1

1

Inside the scriptblock for the CheckStateChanged event, the variable $i is unknown. To make its value available there, you must have stored it in a property the checkbox can read. The best place for this is the checkbox's own Tag property.

In your code, create the checkboxes like this:

$charts = "x","y","z"   # no need to surround this with @()

$checkBox_Charts = [System.Windows.Forms.checkbox[]]::new($charts.Count)
for ($i = 0; $i -lt $charts.Count; $i++){
    $CheckBox = new-object System.Windows.Forms.checkbox
    $height = (60*$i)+20
    $CheckBox.Location = new-object System.Drawing.Size(100,$height)
    $CheckBox.Size = '150,50'
    $CheckBox.Text = $charts[$i]
    $CheckBox.Checked = $false
    # save the index $i in the Tag property of the checkbox itself
    $CheckBox.Tag = $i
    $CheckBox.Add_CheckStateChanged({
        # inside this scriptblock, the variable $i is unknown
        # so we use the index value stored in the Tag property earlier
        Write-Host "CP2: in Add_CheckStateChanged $($this.Checked)"
        Write-Host "CheckBox index: $($this.Tag)"
        Write-Host $checkBox_Charts[$this.Tag]
        Write-Host
    })
    $checkBox_Charts[$i] = $CheckBox
}

Then remove the code you have here:

###########  This is the important piece ##############
#                                                     #
# Do something when the state of the checkbox changes #
#######################################################

for($i=0; $i -lt 2; $i++){
    $checkBox_Charts[$i].Add_CheckStateChanged({
    Write-Host "CP2: in Add_CheckStateChanged " + $checkBox_Charts[$i].Checked
    Write-Host $checkBox_Charts[$i]
    Write-Host $i})

}

because this is now all done while creating the checkboxes earlier (and won't work as you have noticed)


As sidenotes:

  • change this obsolete/deprecated code:

    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
    

    into

    Add-Type -AssemblyName System.Windows.Forms
    Add-Type -AssemblyName System.Drawing

  • straighten the curly quotes you have in $Form.Text = ”My First Form with a working checkbox” to become $Form.Text = "My First Form with a working checkbox".
    They won't hurt you in this case, but using curly quotes in code can lead to numerous weird problems. Never use them in code.

Inside a control's event handler, the $this automatic variable refers to the control itself

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

Comments

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.