Home > Back-end >  Refresh Array checkboxes with Powershell
Refresh Array checkboxes with Powershell

Time:11-06

I am trying to create a script that lets the user choose a server from a drop down list. Each server is mapped to a unique array which goes to a foreach loop. The loop cycles through the array and prints a check box on to the form with the value that is in the array. This works with no issue. The problem is when I select the different Server from the drop down list and click "Select Server" button the new values in the Array do not overwrite the existing values. In other words the check box values on the form are not updating with the new array values. What I would like to happen is when you click the "Select Server" button the check box values update to reflect the array values associated with their corresponding server.

Here is an example.

  1. Choose ServerA from drop down
  2. Select 'Select Server'
  3. The following check boxes will list out on to the form in checkbox's:@('Zero','One','Two','Three')
  4. Now if you click ServerB and select "Select Server" I would expect new check boxes to overwrite the existing check boxes with these values: @('0','1','2','3')

Unfortunately the values do not update. I need to have the array values update when the "Select Server" button is selected... Ive looked around at forums and have found some possible solutions but they all seems to fall short.

Thank you in advance.

function GenerateForm 
{   
$PC=
{
    $hostname = $dropdown.SelectedItem
    
    if ($hostname -eq "ServerA")

        { $CheckBoxLabels = @('Zero','One','Two','Three')
        }
    elseif($hostname -eq "ServerB")
        {
           $CheckBoxLabels = @('0','1','2','3')
     }
        
    $name = New-Object System.Windows.Forms.Label -Property @{
    Text = "Start Time"
    Location = "900, 220"
    ForeColor = "Black"
    Height = 22
    Width = 200
    }
    $form1.Controls.Add($hostname)
        
    $CheckBoxCounter = 1
    
    $CheckBoxes = foreach($Label in $CheckBoxLabels) 
    {   
        $CheckBox = New-Object System.Windows.Forms.CheckBox        
        $CheckBox.UseVisualStyleBackColor = $True
        $System_Drawing_Size = New-Object System.Drawing.Size
        $System_Drawing_Size.Width = 104
        $System_Drawing_Size.Height = 24
        $CheckBox.Size = $System_Drawing_Size
        $CheckBox.TabIndex = 2
    
        $CheckBox.Text = $Label
        
        $System_Drawing_Point = New-Object System.Drawing.Point
        $System_Drawing_Point.X = 27
        # Make sure to vertically space them dynamically, counter comes in handy
        $System_Drawing_Point.Y = 200   (($CheckBoxCounter - 1) * 31) #Controls location on Y axis
        $CheckBox.Location = $System_Drawing_Point
        $CheckBox.DataBindings.DefaultDataSourceUpdateMode = 0

        # Give it a unique name based on our counter
        $CheckBox.Name = "CheckBox$CheckBoxCounter"

       $form1.Controls.Add($CheckBox)

        # return object ref to array
        $Global:CheckBox
        # increment our counter
        $CheckBoxCounter  
    }
    }

    $form1 = New-Object System.Windows.Forms.Form
    $form1.Text = "UCCE Log Collector - Version 2.0"
    $form1.Name = "form1"
    $form1.DataBindings.DefaultDataSourceUpdateMode = 0
    $System_Drawing_Size = New-Object System.Drawing.Size
    $System_Drawing_Size.Width = 1150
    $System_Drawing_Size.Height = 500
    $form1.ClientSize = $System_Drawing_Size

$dropdown = New-Object System.Windows.Forms.ListBox
$dropdown.Location = New-Object System.Drawing.Point(10,50)
$dropdown.Size = New-Object System.Drawing.Size(100,20)
$dropdown.Height = 80

[void] $dropdown.Items.Add('ServerA')
[void] $dropdown.Items.Add('ServerB')


$form1.Controls.Add($dropdown)

    ######### Select Server Button
    $SelectPC = New-Object System.Windows.Forms.Button
    $SelectPC.TabIndex = 4
    $SelectPC.Name = "SelectPC"
    $System_Drawing_Size = New-Object System.Drawing.Size
    $System_Drawing_Size.Width = 120
    $System_Drawing_Size.Height = 30
    $SelectPC.Size = $System_Drawing_Size
    $SelectPC.UseVisualStyleBackColor = $True
    $SelectPC.Text = "Select Server"
    $System_Drawing_Point = New-Object System.Drawing.Point
    $System_Drawing_Point.X = 0 # 0
    $System_Drawing_Point.Y = 150 #150
    $SelectPC.Location = $System_Drawing_Point
    $SelectPC.DataBindings.DefaultDataSourceUpdateMode = 0
    $SelectPC.add_Click($PC)

    $form1.Controls.Add($SelectPC)
    
        $result = $form1.ShowDialog()
    $result

}
GenerateForm

CodePudding user response:

Every time Click/$PC is invoked you are creating four new CheckBoxes at the same coordinates as the existing ones without removing or reusing them. Instead, create the CheckBoxes once (the same way you do with $dropdown and $SelectPC) and then all that's left for Click/$PC to do is update their Text and other properties.

This involves moving all of the Control creation code outside of Click/$PC...

$name = New-Object System.Windows.Forms.Label -Property @{
    Text      = "Start Time"
    Location  = "900, 220"
    ForeColor = "Black"
    Height    = 22
    Width     = 200
}
$form1.Controls.Add($name)

$CheckBoxes = for ($index = 0; $index -lt 4; $index  ) {   
    $CheckBox = New-Object System.Windows.Forms.CheckBox        
    $CheckBox.UseVisualStyleBackColor = $True
    $System_Drawing_Size = New-Object System.Drawing.Size
    $System_Drawing_Size.Width = 104
    $System_Drawing_Size.Height = 24
    $CheckBox.Size = $System_Drawing_Size
    $CheckBox.TabIndex = 2

    # Hide each CheckBox until the first server is selected
    $CheckBox.Visible = $false

    $System_Drawing_Point = New-Object System.Drawing.Point
    $System_Drawing_Point.X = 27
    # Make sure to vertically space them dynamically, counter comes in handy
    $System_Drawing_Point.Y = 200   ($index * 31) #Controls location on Y axis
    $CheckBox.Location = $System_Drawing_Point
    $CheckBox.DataBindings.DefaultDataSourceUpdateMode = 0

    # Give it a unique name based on our counter
    $CheckBox.Name = "CheckBox$index"

    $form1.Controls.Add($CheckBox)

    # return object ref to array
    $CheckBox
}

...and making a few adjustments...

  1. CheckBoxes is now created using a for loop of length 4 since we don't currently have a collection of labels to use.
  2. The Visible property is initialized to $false to maintain the functionality of the CheckBoxes not appearing until a server is selected.
  3. Since $index starts at 0 — unlike $CheckBoxCounter, which started at 1 — this simplifies the calculation of $System_Drawing_Point.Y.

What's left for Click/$PC to do is just iterate through the array of CheckBoxes setting Text to the same-index text in $CheckBoxLabels and ensure the CheckBox is Visible...

$PC = {
    $hostname = $dropdown.SelectedItem

    if ($hostname -eq "ServerA") {
        $CheckBoxLabels = @('Zero', 'One', 'Two', 'Three')
    }
    elseif ($hostname -eq "ServerB") {
        $CheckBoxLabels = @('0', '1', '2', '3')
    }

    # Assume that $CheckBoxLabels is at least as long as $CheckBoxes
    for ($index = 0; $index -lt $CheckBoxes.Length; $index  ) {
        $checkBox = $CheckBoxes[$index]

        $checkBox.Text = $CheckBoxLabels[$index]
        # For demonstration purposes, make all odd-numbered boxes checked
        $checkBox.Checked = $index % 2 -eq 1
        $checkBox.Visible = $true
    }
}

The entire script then becomes this...

function GenerateForm {   
    $PC = {
        $hostname = $dropdown.SelectedItem

        if ($hostname -eq "ServerA") {
            $CheckBoxLabels = @('Zero', 'One', 'Two', 'Three')
        }
        elseif ($hostname -eq "ServerB") {
            $CheckBoxLabels = @('0', '1', '2', '3')
        }

        # Assume that $CheckBoxLabels is at least as long as $CheckBoxes
        for ($index = 0; $index -lt $CheckBoxes.Length; $index  ) {
            $checkBox = $CheckBoxes[$index]

            $checkBox.Text = $CheckBoxLabels[$index]
            # For demonstration purposes, make all odd-numbered boxes checked
            $checkBox.Checked = $index % 2 -eq 1
            $checkBox.Visible = $true
        }
    }

    $form1 = New-Object System.Windows.Forms.Form
    $form1.Text = "UCCE Log Collector - Version 2.0"
    $form1.Name = "form1"
    $form1.DataBindings.DefaultDataSourceUpdateMode = 0
    $System_Drawing_Size = New-Object System.Drawing.Size
    $System_Drawing_Size.Width = 1150
    $System_Drawing_Size.Height = 500
    $form1.ClientSize = $System_Drawing_Size

    $dropdown = New-Object System.Windows.Forms.ListBox
    $dropdown.Location = New-Object System.Drawing.Point(10, 50)
    $dropdown.Size = New-Object System.Drawing.Size(100, 20)
    $dropdown.Height = 80

    [void] $dropdown.Items.Add('ServerA')
    [void] $dropdown.Items.Add('ServerB')

    $form1.Controls.Add($dropdown)

    ######### Select Server Button
    $SelectPC = New-Object System.Windows.Forms.Button
    $SelectPC.TabIndex = 4
    $SelectPC.Name = "SelectPC"
    $System_Drawing_Size = New-Object System.Drawing.Size
    $System_Drawing_Size.Width = 120
    $System_Drawing_Size.Height = 30
    $SelectPC.Size = $System_Drawing_Size
    $SelectPC.UseVisualStyleBackColor = $True
    $SelectPC.Text = "Select Server"
    $System_Drawing_Point = New-Object System.Drawing.Point
    $System_Drawing_Point.X = 0 # 0
    $System_Drawing_Point.Y = 150 #150
    $SelectPC.Location = $System_Drawing_Point
    $SelectPC.DataBindings.DefaultDataSourceUpdateMode = 0
    $SelectPC.add_Click($PC)

    $form1.Controls.Add($SelectPC)

    $name = New-Object System.Windows.Forms.Label -Property @{
        Text      = "Start Time"
        Location  = "900, 220"
        ForeColor = "Black"
        Height    = 22
        Width     = 200
    }
    $form1.Controls.Add($name)

    $CheckBoxes = for ($index = 0; $index -lt 4; $index  ) {   
        $CheckBox = New-Object System.Windows.Forms.CheckBox        
        $CheckBox.UseVisualStyleBackColor = $True
        $System_Drawing_Size = New-Object System.Drawing.Size
        $System_Drawing_Size.Width = 104
        $System_Drawing_Size.Height = 24
        $CheckBox.Size = $System_Drawing_Size
        $CheckBox.TabIndex = 2

        # Hide each CheckBox until the first server is selected
        $CheckBox.Visible = $false

        $System_Drawing_Point = New-Object System.Drawing.Point
        $System_Drawing_Point.X = 27
        # Make sure to vertically space them dynamically, counter comes in handy
        $System_Drawing_Point.Y = 200   ($index * 31) #Controls location on Y axis
        $CheckBox.Location = $System_Drawing_Point
        $CheckBox.DataBindings.DefaultDataSourceUpdateMode = 0

        # Give it a unique name based on our counter
        $CheckBox.Name = "CheckBox$index"

        $form1.Controls.Add($CheckBox)

        # return object ref to array
        $CheckBox
    }
    
    $result = $form1.ShowDialog()
    $result
}
GenerateForm
  • Related