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'}
}
}
}