Home > Blockchain >  Poweshell Script GUI selections are appending strings instead of new entries in the array
Poweshell Script GUI selections are appending strings instead of new entries in the array

Time:12-10

I have a GUI in my .ps1, and I declared what I think of as an arraylist, $choice = @() to store selected options. Whenever you select anything in the GUI, it adds "Option [#]" to the list. The first time, it does it correctly. each entry you select makes a new line. however, if you deselect one, and reselect it, it appends the string. so instead of the list being:

$choice = (
Option 1
Option 3
)

It is now

$choice= (
Option 1Option 3
)

Here is the full script.

# Set the initial choices
$choice = @()

# Use a while loop to keep the menu open until the user selects the "Exit" option
while ($true) {
    # Clear the screen
    Clear-Host

    # Use a foreach loop to display each menu option, including an asterisk on the selected options
    foreach ($option in "Option 1", "Option 2", "Option 3", "Option 0", "Exit") {
        if ($choice -contains $option) {
            Write-Host "$option *"
        } elseif ($option -eq "Option 0") {
            # "Option 0" is not a selectable option, so always display it as deselected
            Write-Host $option
        } else {
            Write-Host $option
        }
    }

    # Prompt the user to enter their selection
    $userInput = Read-Host "Enter your selection"

    # Use a switch statement to execute the selected options
    switch -regex ($userInput)
    {
        "0" {
            # Code for Option 0
            # Print the selected options and exit the script
            Write-Warning "Choices variable: $choice"
            Write-Host "Selected options: "
            switch ($choice) {
                "Option 1" { 
                    Write-Host "1"
                }
                "Option 2" {
                    Write-Host "2"
                }
                "Option 3" {
                    Write-Host "3"
                }
                default {
                    Write-Host "No selected options."
                }
            }
            # Return to exit the current iteration of the while loop
            return
        }
        "1" {
            # Code for Option 1
            # Check if the user has already selected this option
            if ($choice -contains "Option 1") {
                # Remove the option from the $choice variable
                $choice = $choice | Where-Object {$_ -ne "Option 1"}
            } else {
                # Add the option to the $choice variable
                $choice  = "Option 1"
            }
        }
        "2" {
            # Code for Option 2
            # Check if the user has already selected this option
            if ($choice -contains "Option 2") {
                # Remove the option from the $choice variable
                $choice = $choice | Where-Object {$_ -ne "Option 2"}
            } else {
                # Add the option to the $choice variable
                $choice  = "Option 2"
            }
        }
        "3" {
            # Code for Option 3
            # Check if the user has already selected this option
            if ($choice -contains "Option 3") {
                # Remove the option from the $choice variable
                $choice = $choice | Where-Object {$_ -ne "Option 3"}
            } else {
                # Add the option to the $choice variable
                $choice  = "Option 3"
            }
        }
        "4" {
            # Code for Exit
            # Break out of the while loop to end the script
            break
        }
        default {
            
        # Code for invalid selection or deselection
        # Check if the user has deselected an option
        if ($choice -contains $userInput) {
            # Remove the option from the $choice variable
            $choice = $choice | Where-Object {$_ -ne $userInput}
        }   else {
                # The user has entered an invalid selection
                Write-Host "Invalid selection"
            }
        }
    }
}

I for the life of me can't figure out why removing something from the list breaks the ability to add new items to the list.

CodePudding user response:

Continuing from my comment.

If you are trying to add/remove from a list, then you should avoid using this: $choice = @(). Instead, use $arrlist = New-Object -TypeName System.Collections.ArrayList, and instead of =, use $arrlist.Add("SomeValue") and $arrlist.Remove("SomeValue").

Example:

$arrlist = New-Object -TypeName System.Collections.ArrayList

$arrlist.Add("One")
$arrlist.Add("Two")

$arrlist
# Results
<#
0
1
One
Two
#>

$arrlist.Add("Three")
# Results
<#
2
#>

$arrlist
# Results
<#
One
Two
Three
#>

$arrlist.Remove("Two")

$arrlist
# Results
<#
One
Three
#>

So, a refactor of your code might look like this:

$choice = New-Object -TypeName System.Collections.ArrayList

while ($true) 
{
    Clear-Host

    foreach ($option in 'Option 1', 'Option 2', 'Option 3', 'Option 0', 'Exit') 
    {
        if ($choice -contains $option) 
        {"$option *"} 
        elseif ($option -eq 'Option 0') 
        {$option} 
        else {$option}
    }

    # Prompt the user to enter their selection
    $userInput = Read-Host 'Enter your selection'

    # Use a switch statement to execute the selected options
    switch -regex ($userInput)
    {
        '0' 
        {
            Write-Warning -Message 'Choices variable: $choice'
            'Selected options: '
            switch ($choice) {
                'Option 1' {'1'}
                'Option 2' {'2'}
                'Option 3' {'3'}
                default {'No selected options.'}
            }

            return
        }
        '1' {
            if ($choice -contains 'Option 1') 
            {
                $choice = $choice | 
                Where-Object {$PSItem -ne 'Option 1'}
            } 
            else {$choice.Add('Option 1')}
        }
        '2' 
        {
            if ($choice -contains 'Option 2') 
            {
                $choice = $choice | 
                Where-Object {$PSItem -ne 'Option 2'}
            } 
            else {$choice.Add('Option 2')}
        }
        '3' 
        {
            if ($choice -contains 'Option 3') 
            {
                $choice = $choice | 
                Where-Object {$PSItem -ne 'Option 3'}
            } 
            else {$choice.Remove('Option 3')}
        }
        '4' {break}
        default 
        {            
            if ($choice -contains $userInput) 
            {
                $choice = $choice | 
                Where-Object {$PSItem -ne $userInput}
            }   
            else {Write-Warning -Message 'Invalid selection'}
        }
    }
}
  • Related