powershell checkbox generated dynamically to array

PHILIPPE Marc 1 Reputation point
2021-10-12T18:28:39.577+00:00

Hello,

i have a form in which the checkboxes are generated dynamically reading a file.

I'm trying to have the text of the checkboxes being added to an array if they are checked or removed from the array if the are unchecked .

Ihere the code i wrote . It does not work but i do no know why .

function checkbox_test{

$instances = [System.Collections.ArrayList]@()  


[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 = 2000  
$Form.height = 1000  
$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  

# create your checkbox   


Clear-Host  

$moduleemplacment="D:\PowerShell\modules"

$EmplacementFichier = "D:\PowerShell\instanceliste.txt"
$MonFichier = get-content $EmplacementFichier
$a=1
$b=50
$c=30
$checkboxes= foreach ($UneLigne in $MonFichier){

$varcheckbox=-join("$checkbox",$a)  
$varcheckbox = new-object System.Windows.Forms.checkbox                              
$varcheckbox.Location = new-object System.Drawing.Size($b,$c)  
$varcheckbox.Size = new-object System.Drawing.Size(250,50)                              
$varcheckbox.Text = $UneLigne  
$varcheckbox.Checked = $true                              
$Form.Controls.Add($varcheckbox)   
$instances.Add($varcheckbox.Text)   




$c=$c+50  

$a=$a+1  



                                }  



# Add an OK button  
$OKButton = new-object System.Windows.Forms.Button  
$OKButton.Location = new-object System.Drawing.Size(130,300)  
$OKButton.Size = new-object System.Drawing.Size(100,40)  
$OKButton.Text = "OK"  
$OKButton.Add_Click({  
 foreach($CheckBox in $CheckBoxes) {  

                write-host $CheckBox.Text  
                if (!($CheckBox.Checked ))  

                {  

                $instances.remove($CheckBox.Text)   
                }  
                                    }  



[System.Windows.Forms.MessageBox]::Show($instances)  




})  


$form.Controls.Add($OKButton)  

#Add a cancel button  
$CancelButton = new-object System.Windows.Forms.Button  
$CancelButton.Location = new-object System.Drawing.Size(255,300)  
$CancelButton.Size = new-object System.Drawing.Size(100,40)  
$CancelButton.Text = "Cancel"  
$CancelButton.Add_Click({$Form.Close()})  
$form.Controls.Add($CancelButton)  

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

$checkbox1.Add_CheckStateChanged({

$OKButton.Enabled = $checkbox1.Checked })

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

}

Call the function

checkbox_test

Windows for business Windows Server User experience PowerShell
{count} votes

4 answers

Sort by: Most helpful
  1. Rich Matheisen 47,901 Reputation points
    2021-10-12T19:09:19.76+00:00

    Well, firstly you have this statement in your code (about line #51):

    $varcheckbox = -join ("$checkbox", $a)
    

    But the variable "$checkbox" is not yet defined or initialized. Also, the quotes surrounding that variable name are unnecessary. Perhaps you meant to use only the string "checkbox"?

    And on (about) line #82 and 83, you once again use an undefined variable, this one is $checkbox1:

    $checkbox1.Add_CheckStateChanged( {
                $OKButton.Enabled = $checkbox1.Checked })
    

    Make those two corrections first. You might also want to add "Set-StrictMode -Version Latest" to help with finding and fixing any other "transgressions" in the code.

    0 comments No comments

  2. PHILIPPE Marc 1 Reputation point
    2021-10-13T06:56:00.057+00:00

    Hello,

    First thanks for your answer, no i mean the string "$checkbox".
    line 83-83 are commented


  3. PHILIPPE Marc 1 Reputation point
    2021-10-13T07:52:34.41+00:00

    Hello,

    i found a script on which i can based my work https://stackoverflow.com/questions/32278589/how-do-i-dynamically-create-check-boxes-from-an-array-using-the-form

    function GenerateForm {
    param(
    [string[]]$CheckBoxLabels
    )

    Keep track of number of checkboxes

    $CheckBoxCounter = 1

    When we create a new textbox, we add it to an array for easy reference later

    $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

    # Assign text based on the input  
    $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 = 13 + (($CheckBoxCounter - 1) * 31)  
    $CheckBox.Location = $System_Drawing_Point  
    $CheckBox.DataBindings.DefaultDataSourceUpdateMode = 0  
    
    # Give it a unique name based on our counter  
    $CheckBox.Name = "CheckBox$CheckBoxCounter"  
    
    # Add it to the form  
    $form1.Controls.Add($CheckBox)  
    # return object ref to array  
    $CheckBox  
    # increment our counter  
    $CheckBoxCounter++  
                                                   }  
    

    $handler_button1_Click=
    {
    $listBox1.Items.Clear();

    # Keep track of whether something has been added to the list  
    $ContentPresent = $false  
    # Iterate over the checkboxes, one by one  
    foreach($CheckBox in $CheckBoxes){  
        if($CheckBox.Checked){  
            $listBox1.Items.Add("{0} (with value ""{1}"") has been checked" -f ($CheckBox.Name,$CheckBox.Text))  
            $ContentPresent = $True  
        }  
    }  
    
    # If something was already added to the list, no need to show default message  
    if (-not $ContentPresent) { $listBox1.Items.Add("No CheckBox selected....") }   
    

    }

    }

    GenerateForm -CheckBoxLabels "test1"

    but when i run it i have :

    GenerateForm -CheckBoxLabels "test1"
    Impossible d’appeler une méthode dans une expression Null.
    Au caractère Ligne:32 : 5

    • $form1.Controls.Add($CheckBox)
    • ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    • CategoryInfo : InvalidOperation : (:) [], RuntimeException
    • FullyQualifiedErrorId : InvokeMethodOnNull

    any clues ?

    thanks,


  4. PHILIPPE Marc 1 Reputation point
    2021-10-13T13:28:53.723+00:00

    Hello,

    here the new version :

    function GenerateForm {
    param(
    [Array[]]$CheckBoxLabelsInstances,
    [Array[]]$CheckBoxLabelsModules
    )

    Keep track of number of CheckBoxesInstances

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

    $instances = [System.Collections.ArrayList]@()

    $modules = [System.Collections.ArrayList]@()
    $form1 = New-Object System.Windows.Forms.Form
    $form1.Text = "Primal Form"
    $form1.Name = "form1"
    $form1.DataBindings.DefaultDataSourceUpdateMode = 0
    $System_Drawing_Size = New-Object System.Drawing.Size
    $System_Drawing_Size.Width = 2000
    $System_Drawing_Size.Height = 2000
    $form1.ClientSize = $System_Drawing_Size

    $button1 = New-Object System.Windows.Forms.Button
    $button1.Text = "Run Script"

    $System_Drawing_Point = New-Object System.Drawing.Point
    $System_Drawing_Point.X = 27
    $System_Drawing_Point.Y = 156
    $button1.Location = $System_Drawing_Point
    $button1.DataBindings.DefaultDataSourceUpdateMode = 0

    $form1.Controls.Add($button1)
    $button1.add_Click({

    $listBox1.Items.Clear();  
    
    # Keep track of whether something has been added to the list  
    $ContentPresent = $false  
    # Iterate over the CheckBoxesInstances, one by one  
    foreach($CheckBoxInstance in $CheckBoxesInstances){  
        if(!($CheckBoxInstance.Checked)){  
            write-host $CheckBoxInstance.Text  
            $instances.remove($CheckBoxInstance.Text)   
            write-host  " nouveau " $instances  
            $ContentPresent = $True  
        }  
    }  
    

    })

    $CheckBoxCounterInstance = 1

    When we create a new textbox, we add it to an array for easy reference later

    $CheckBoxesInstances = foreach($LabelInstance in $CheckBoxLabelsInstances) {
    $CheckBoxInstance = New-Object System.Windows.Forms.CheckBox
    $CheckBoxInstance.UseVisualStyleBackColor = $True
    $CheckBoxInstance.Checked = $True
    $System_Drawing_Size = New-Object System.Drawing.Size
    $System_Drawing_Size.Width = 104
    $System_Drawing_Size.Height = 24
    $CheckBoxInstance.Size = $System_Drawing_Size
    $CheckBoxInstance.TabIndex = 2

    # Assign text based on the input  
    $CheckBoxInstance.Text = $LabelInstance  
      
    $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 = 13 + (($CheckBoxCounterInstance - 1) * 31)  
    $CheckBoxInstance.Location = $System_Drawing_Point  
    $CheckBoxInstance.DataBindings.DefaultDataSourceUpdateMode = 0  
    
    # Give it a unique name based on our counter  
    $CheckBoxInstance.Name = "CheckBoxInstance$CheckBoxCounterInstance"  
    
    # Add it to the form  
    $form1.Controls.Add($CheckBoxInstance)  
    # return object ref to array  
    $CheckBoxInstance  
    # increment our counter  
    $CheckBoxCounterInstance++  
    $instances.Add($CheckBoxInstance.Text)   
                                                   }  
    

    $CheckBoxCounterModule = 1

    $CheckBoxesModules = foreach($LabelModule in $CheckBoxLabelsModules) {
    $CheckBoxModule = New-Object System.Windows.Forms.CheckBox
    $CheckBoxModule.UseVisualStyleBackColor = $True
    $CheckBoxModule.Checked = $True
    $System_Drawing_Size = New-Object System.Drawing.Size
    $System_Drawing_Size.Width = 104
    $System_Drawing_Size.Height = 24
    $CheckBoxModule.Size = $System_Drawing_Size
    $CheckBoxModule.TabIndex = 2

    # Assign text based on the input  
    $CheckBoxModule.Text = $LabelModule  
      
    $System_Drawing_Point = New-Object System.Drawing.Point  
    $System_Drawing_Point.X = 50  
    # Make sure to vertically space them dynamically, counter comes in handy  
    $System_Drawing_Point.Y = 13 + (($CheckBoxCounterModule - 1) * 31)  
    $CheckBoxModule.Location = $System_Drawing_Point  
    $CheckBoxModule.DataBindings.DefaultDataSourceUpdateMode = 0  
    
    # Give it a unique name based on our counter  
    $CheckBoxModule.Name = "CheckBoxModule$CheckBoxCounterModule"  
    
    # Add it to the form  
    $form1.Controls.Add($CheckBoxModule)  
    # return object ref to array  
    $CheckBoxModule  
    # increment our counter  
    $CheckBoxCounterModule++  
    $Modules.Add($CheckBoxModule.Text)   
                                                   }  
    

    write-host "instances : "$instances

    $form1.Add_Shown({$Form1.Activate()})  
    [void] $form1.ShowDialog()   
    

    }

    $moduleemplacment="D:\PowerShell\modules"
    $EmplacementFichier = "D:\PowerShell\instanceliste.txt"
    $MonFichier = get-content $EmplacementFichier

    $lines= foreach ($UneLigne in $MonFichier){

    $UneLigne
    }

    $modules = Get-ChildItem -Path $moduleemplacment -Directory |
    Foreach-Object {
    $myobj1name=$_.Name

                    }  
    

    write-host $modules
    GenerateForm -CheckBoxLabelsInstances $lines -CheckBoxLabelsModules $modules

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.