PowerShell Studio dynamic checkbox naming issue - checkbox

giving the following PowerShell Studio Code, how can I call and disable the 'David Checkbox' under the 'Checkit' button. I know I am messing up on the checkbox declaration somehow because powershell does not recognize my checkbox as an object:
The property 'Enabled' cannot be found on this object. Verify that the property exists and can be set.
$accounts = "David", "Dave"
$buttonLoadLabels_Click = {
$CheckBoxCounter = 1
$accounts = 'didier','david'
foreach ($account in $accounts)
{
$label = New-Object System.Windows.Forms.Label
$label.Text = $account
$label.TextAlign = 'MiddleCenter'
$label.Font = $label1.Font
$flowlayoutpanel1.Controls.Add($label)
$CB = New-Object System.Windows.Forms.CheckBox
$CB.Name = $account
Write-Host $CB.Name
$flowlayoutpanel1.Controls.Add($CB)
}
}
$buttonCheckIt_Click = {
$checkbox_David.Enabled = $false
}

Related

Powershell GUI not registering Radio Button as clicked [duplicate]

This question already has answers here:
WPF if statement based on radio button checked or not
(3 answers)
Closed 1 year ago.
I have the following code:
$var_executeButton.Add_Click( {
if ($var_radioButton.Checked) {
..do stuff
}
})
however, the code inside the if block never run, even if radio button is checked.
Code outside of the if works just fine.
Can you please tell me why?
Continuing from my comment. There ways to take action on form elements at the time they are acted on or checked later. As an example here is a simple WinForm, that discovers all radio button controls on a form and takes the same action when any one of them is clicked.
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
$objForm = New-Object System.Windows.Forms.Form
$objForm.Text = "Test"
$objForm.Size = New-Object System.Drawing.Size(400, 200)
$objForm.StartPosition = "CenterScreen"
$RadioButton1 = New-Object System.Windows.Forms.RadioButton
$RadioButton1.Location = New-Object System.Drawing.Size(10, 10)
$RadioButton1.Size = New-Object System.Drawing.Size(100, 20)
$RadioButton1.Checked = $false
$RadioButton1.text = "Button1"
$objForm.controls.Add($RadioButton1)
$RadioButton2 = New-Object System.Windows.Forms.RadioButton
$RadioButton2.Location = New-Object System.Drawing.Size(10, 50)
$RadioButton2.Size = New-Object System.Drawing.Size(100, 20)
$RadioButton2.Checked = $false
$RadioButton2.text = "Button2"
$objForm.controls.Add($RadioButton2)
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(10, 120)
$OKButton.Size = New-Object System.Drawing.Size(150, 30)
$OKButton.Text = "OK"
$OKButton.Enabled = $false
$OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$objForm.Controls.Add($OKButton)
$objForm.AcceptButton = $OKButton
$objForm.TopMost = $True
$objForm.Controls |
Where-Object { $PSItem -is [System.Windows.Forms.RadioButton] } |
ForEach-Object {
$PSItem.Add_Click(
{
If (-Not $OKButton.Enabled)
{$OKButton.Enabled = $True}
})
}
$Form = $objForm.ShowDialog()
To see if a radio button is checked, you can use either .Checked,
# Example - check radio button state on OK click.
function Test-RadioButtonCheck
{
Param
(
$title,
$a1,
$a2,
$a3
)
$form = New-Object System.Windows.Forms.Form
$form.Size = '300,250'
$form.Text = $title
$form.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen
$label1 = New-Object System.Windows.Forms.Label
$label1.Location = '15,15'
$label1.Width = 100
$label1.Text = 'Enter some text'
$form.Controls.Add($label1)
$textBox1 = New-Object System.Windows.Forms.TextBox
$textBox1.Location = '115,15'
$textBox1.width = 150
$textBox1.Name = 'input'
$form.Controls.Add($textBox1)
$radio1 = New-Object System.Windows.Forms.RadioButton
$radio1.Location = '25,40'
$radio1.Text = 'Check me if you want the save'
$radio1.Width = 200
$form.Controls.Add($radio1)
$button = New-Object System.Windows.Forms.Button
$button.Location = '70,70'
$button.Text = 'Ok'
$button.DialogResult = 'Ok'
$form.Controls.Add($button)
if($form.ShowDialog() -eq 'Ok')
{
if($textBox1.Text)
{
if($radio1.Checked){$form}
else{[void][System.Windows.Forms.MessageBox]::Show('You didn''t check the radio button','Error')}
}
else{[void][System.Windows.Forms.MessageBox]::Show('You didn''t enter any text','Error')}
}
}
if($frm = Test-RadioButtonCheck 'Test form')
{Write-Host "You entered $($frm.Controls['input'].Text)" -ForegroundColor Green}
.IsChecked as per mklement0's link, or looping to find them:
Where {$PSItem -is [system.windows.controls.radiobutton] -and $PSItem.IsChecked} |
Select Name
... or using [System.Windows.Controls.RadioButton]::CheckedEvent as per this WPF example:
[xml]$xaml = #"
<Window
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
x:Name = "Window" Title = "Initial Window" WindowStartupLocation = "CenterScreen"
SizeToContent = "WidthAndHeight" ShowInTaskbar = "True" Background = "lightgray">
<StackPanel x:Name = 'StackPanel'>
<RadioButton x:Name = "Item1" Content = 'Item1'/>
<RadioButton x:Name = "Item2" Content = 'Item2'/>
<RadioButton x:Name = "Item3" Content = 'Item3'/>
<Separator/>
<TextBox x:Name = 'textbox'/>
</StackPanel>
</Window>
"#
$reader = (New-Object System.Xml.XmlNodeReader $xaml)
$Window = [Windows.Markup.XamlReader]::Load( $reader )
$xaml.SelectNodes("//*[#*[contains(translate(name(.),'n','N'),'Name')]]") |
ForEach {Set-Variable -Name ($PSItem.Name) -Value $Window.FindName($PSItem.Name) -Scope Script}
#Bubble up event handler
[System.Windows.RoutedEventHandler]$Script:CheckedEventHandler =
{$TextBox.Text = $PSItem.source.name}
$StackPanel.AddHandler([System.Windows.Controls.RadioButton]::
CheckedEvent, $CheckedEventHandler)
$Window.Showdialog() | Out-Null
If you want dig at the explanations of the WPF and radio button options, then see this blog post regarding the samples shown:
https://learn-powershell.net/2014/08/10/powershell-and-wpf-radio-button
If the aforementioned is not what you are doing, then as per my comment, you are not showing what the use case really is.

Uncheck a checkbox after if statement

I am creating an admin tool for our helpdesk and I want the option to allow the tool to stay on top of other windows via a checkbox. This is the inital setup of the checkbox:
$cbx_OnTop = New-Object system.Windows.Forms.CheckBox
$cbx_OnTop.text = "Keep On Top"
$cbx_OnTop.AutoSize = $false
$cbx_OnTop.width = 175
$cbx_OnTop.height = 20
$cbx_OnTop.location = New-Object System.Drawing.Point(24,290)
$cbx_OnTop.Font = 'Microsoft Sans Serif,8'
$cbx_OnTop.Checked = $false
I then have the following function:
function KeepOnTop {
if ($cbx_OnTop.Checked = $True) {
$AdminTool.TopMost = $True
} else {
$AdminTool.TopMost = $false
}
}
How do I add the function to this checkbox?
The Add_CheckStateChanged event is the command you are looking for.
$cbx_OnTop.Add_CheckStateChanged({
If ($cbx_OnTop.Checked) {
$AdminTool.TopMost = $True
} Else {
$AdminTool.TopMost = $false
}
)}

Build and respond to events on multiple check boxes

I am attempting to make a form with multiple check boxes, based on the array passed to the form creation function. I can calculate the correct location based on the count of what checkbox I am at is, but I am having trouble (I think) dealing with events. I have this for now (partial code, obviously)
$checkboxCount = 1
foreach ($year in $years) {
$checkbox = new-object System.Windows.Forms.checkbox
$checkbox.Size = new-object System.Drawing.Size(100,20)
$checkbox.Location = new-object System.Drawing.Size(10,($checkbox.Size.Height*$checkboxCount-10))
$checkbox.Text = "Revit $year"
$checkbox.Checked = $true
$Form.Controls.Add($checkbox)
$checkbox.Add_CheckStateChanged({
$results.$year = $checkbox.Checked
})
$checkboxCount ++
}
and the check boxes are created correctly, but when I return $results from the function they are all True. I am basing the code off of this, which works but with a static number of check boxes.
function checkbox_test{
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
$results = #{
one = $true
two = $true
}
$optionCount = 2
# Set the size of your form
$Form = New-Object System.Windows.Forms.Form
$Form | Format-List *
$form.FormBorderStyle = 'FixedDialog'
$form.ShowInTaskbar = $false
$Form.width = 300
$Form.height = 150
$Form.Text = ”Px Tools Updater”
# 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
$checkbox1 = new-object System.Windows.Forms.checkbox
$checkbox1.Location = new-object System.Drawing.Size(10,7)
$checkbox1.Size = new-object System.Drawing.Size(100,20)
$checkbox1.Text = "One"
$checkbox1.Checked = $true
$Form.Controls.Add($checkbox1)
# create your checkbox
$checkbox2 = new-object System.Windows.Forms.checkbox
$checkbox2.Location = new-object System.Drawing.Size(10,27)
$checkbox2.Size = new-object System.Drawing.Size(100,20)
$checkbox2.Text = "Two"
$checkbox2.Checked = $true
$Form.Controls.Add($checkbox2)
# Add an OK button
$OKButton = new-object System.Windows.Forms.Button
$OKButton.Location = new-object System.Drawing.Size(10,70)
$OKButton.Size = new-object System.Drawing.Size(60,30)
$OKButton.Text = "OK"
$OKButton.Add_Click({$Form.Close()})
$form.Controls.Add($OKButton)
#Add a cancel button
$CancelButton = new-object System.Windows.Forms.Button
$CancelButton.Location = new-object System.Drawing.Size(225,100)
$CancelButton.Size = new-object System.Drawing.Size(60,30)
$CancelButton.Text = "Cancel"
$CancelButton.Margin = 0
$CancelButton.Add_Click({$Form.Close()})
$form.Controls.Add($CancelButton)
$checkbox1.Add_CheckStateChanged({
$results.one = $checkbox1.Checked
})
$checkbox2.Add_CheckStateChanged({
$results.two = $checkbox2.Checked
})
# Activate the form
$Form.Add_Shown({$Form.Activate()})
[void] $Form.ShowDialog()
$results
}
I am not sure if I am going wrong with the way I am referencing the results hash table, or maybe the entire approach is wrong?
Edit: I had a thought, that $year is meaningless in the event handler, so I added
$checkbox.Name = $year
and revised the event handler to
$results.($checkbox.Name) = $checkbox.Checked
and
$results.($Self.Name) = $checkbox.Checked
But no joy with either. But what is weird is that using $self results in an odd extra key being added to $return. It has no key name, but the value matches the last change made to any checkbox.
EDIT #2: In further testing, I changed the handler to
$results.2019 = $checkbox.Checked
expecting that to mean any change results in that change applied to the 2019 key. not so. So I am thinking it relates to the way hash tables are passed and referenced and likely I am doing this all wrong. Perhaps worrisome is the fact that I can find tons of information on making check boxes react to and change other parts of the form, but so far nothing on just getting results back.
EDIT #3: OK, seems the answer (of sorts) is there is no need for event handlers, because I only really care about end state anyway. So, with some extra cleanup to also handle Cancel I have this, and it works. Still curious how, or if, I could interact directly with $results from an event handler though.
function checkbox_test{
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
$years = #('2016', '2017', '2018', '2019')
$optionCount = $years.Count
# Set the size of your form
$Form = New-Object System.Windows.Forms.Form
$form.FormBorderStyle = 'FixedDialog'
$form.ShowInTaskbar = $false
$Form.width = 300
$Form.height = ($years.Count * 30 + 50 + 40) #150
$Form.Text = ”Px Tools Updater”
# 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 Checkboxes
$checkboxCount = 1
foreach ($year in $years) {
$checkbox = new-object System.Windows.Forms.checkbox
$checkbox.Size = new-object System.Drawing.Size(100,20)
$checkbox.Location = new-object System.Drawing.Size(10,($checkbox.Size.Height*$checkboxCount-10))
$checkbox.Text = "Revit $year"
$checkbox.Name = $year
$checkbox.Checked = $true
$Form.Controls.Add($checkbox)
$checkboxCount ++
}
# Add an OK button
$OKButton = new-object System.Windows.Forms.Button
$OKButton.Size = new-object System.Drawing.Size(60,30)
$OKButton.Location = new-object System.Drawing.Size(10,($form.DisplayRectangle.Height - $OKButton.Size.Height - 10))
$OKButton.Text = "OK"
$OKButton.Add_Click({
$Form.DialogResult = [System.Windows.Forms.DialogResult]::OK
$Form.Close()
})
$form.Controls.Add($OKButton)
#Add a cancel button
$CancelButton = new-object System.Windows.Forms.Button
$CancelButton.Size = new-object System.Drawing.Size(60,30)
$CancelButton.Location = new-object System.Drawing.Size(($form.DisplayRectangle.Width - $CancelButton.Size.Width - 10),($form.DisplayRectangle.Height - $CancelButton.Size.Height - 10))
$CancelButton.Text = "Cancel"
$CancelButton.Add_Click({
$Form.Close()
})
$form.Controls.Add($CancelButton)
# Activate the form
$Form.Add_Shown({$Form.Activate()})
if ($Form.ShowDialog() -eq 'OK') {
$results = New-Object Collections.Specialized.OrderedDictionary
foreach ($control in $form.Controls) {
if ($years -contains $control.Name) {
$results.Add($control.Name, $control.Checked)
}
}
} else {
$results = $null
}
[void] $Form.Dispose
$results
}
#Call the function
$returned = checkbox_test
Foreach ($key in $returned.keys) {
Write-Host "[$key] $($returned.$key)!"
}
The foreach loop used to assign each checkbox event handler above effectively overwrites the previous one, and therefore you only capture the last one. (2019)
Instead, assign the event hander the way it's traditionally done in Windows Forms:
$results = New-Object Collections.Specialized.OrderedDictionary;
foreach ($year in $years) {
$checkbox = new-object System.Windows.Forms.checkbox
$Form.Controls.Add($checkbox);
$checkbox.Size = new-object System.Drawing.Size(100,20)
$checkbox.Location = new-object System.Drawing.Size(10,($checkbox.Size.Height*$checkboxCount-10))
$checkbox.Text = "Revit $year"
$checkbox.Name = $year
$checkbox.Checked = $true
$results.Add($year, $checkbox.Checked);
# HERE!
$checkbox.Add_CheckStateChanged({
# $this -eq sender, optionally $_ -eq EventArgs
$year = $this.name;
$results.$year = $this.Checked;
});
$checkboxCount++
}

PowerShell DataGridView ComboBoxColumn Default Value

I'm trying to set the default value for DataGridViewComboBoxColumn to be a variable, but I can't find which property to set.
$Column2 = New-Object System.Windows.Forms.DataGridViewComboBoxColumn
$Column2.width = 60
$Column2.name = "Status"
$Column2.DataSource = $DropDownArray
$DataGrid.Columns.Add($Column2)
I've tried:
$Column2.Value = "C"
$Column2.ValueMember = $DDI
$Column2.DataPropertyName = $DDI
$Column2.DisplayMember = $DDI
$Column2.Text = $DropDown.SelectedItem
If($Column2.Index -ge "0"){$Column2.ValueMember = "C"}
$DDI calls back to an array item.
Assistance is appreciated.
Edit
I am not communicating this well enough, I assume. Here is what I have so far (ignore all the commented out stuff, of course):
$null=[reflection.assembly]::LoadWithPartialName("System.Windows.Forms")
$null=[reflection.assembly]::LoadWithPartialName("System.Drawing")
#Initialize DataGrid stuff
$form = new-object System.Windows.Forms.Form
$form.Size = new-object System.Drawing.Size 800,400
$DataGrid = new-object System.Windows.Forms.DataGridView
#$DataGrid = new-object System.windows.forms.DataGrid
$DataGrid.AutoSize = $True
$DataGrid.EditMode = 'EditOnEnter'
#$DataGrid.BeginEdit()
[array]$DropDownArray = "FVR","C","O","P"
#$DropDownArray = #(Import-Csv "$BkpLoc\array.csv")
#This creates the Ok button and sets the event
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(750,375)
$OKButton.Size = New-Object System.Drawing.Size(150,125)
$OKButton.Text = "OK"
$OKButton.Add_Click({$form.Close()})
$OKButton.TabIndex = 9
$array= new-object System.Collections.ArrayList
$data=#(Import-CSV $SAMTemp2)
$array.AddRange($data)
$DataGrid.DataSource = $array
#$DataGrid.Columns.Remove($array.Status)
#Figure out how to set the array to read-only
#$array.IsReadOnly
$Column1 = New-Object System.Windows.Forms.DataGridViewCheckBoxColumn
$Column1.width = 60
$Column1.name = "Planned"
$DataGrid.Columns.Add($Column1)
$Column2 = New-Object System.Windows.Forms.DataGridViewComboBoxColumn
$Column2.width = 60
$Column2.name = "Status"
$Column2.DataSource = $DropDownArray
$DataGrid.Columns.Add($Column2)
#$Column2.Selected = $DropDownArray[1]
#$Column2.DisplayMember = "Status"
#$Column2.DataPropertyName = $DropDownArray[1]
#$Column2.ValueMember = $DropDownArray.Item(1)
$array = New-Object System.Collections.ArrayList
$form.refresh()
#finally show display the Grid
$DataGrid.Dock = [System.Windows.Forms.DockStyle]::Fill
$form.Controls.Add($DataGrid)
$form.controls.add($OKButton)
$form.topmost = $true
$null = $form.showdialog()
My goal here is to have $Column1 available to check if the task was planned that day (up to the user) and $Column2 to default to the status in the export (FVR, C, O or P), allowing the user to change it to another option if the data is incorrect. So ultimately I would like the default to be set based on a statement like:
If($_.Status -eq "Open"){$Column2.ValueMember = <WHATEVER IT TAKES TO GET THE CURRENT VALUE TO "O">
$Column2.DataPropertyName = <WHATEVER IT TAKES TO GET THE CURRENT VALUE TO "O">
$Column2.DisplayMember = <WHATEVER IT TAKES TO GET THE CURRENT VALUE TO "O">
And the same for each value. ($_.Status is one of the columns in the imported CSV.) Right now I just can't get it right. Should there be more to my array than just the 4 values? Everything I try right now for ValueMember comes back saying Field called -WHATEVER- does not exist.
When you add rows to or data bind your DataGridView you will specify the default or selected value for that column then and it'll get translated to your combobox. ValueMember is what you're looking for as it's associated with the data's actual value as opposed to what's displayed in the combobox (DisplayMember). ValueMember and DisplayMember can be the same but they don't have to be.
See below example. This will create a data source of color names and RGB values.
# Datatable for your CSV content
$DataTable1 = New-Object System.Data.DataTable
[void] $DataTable1.Columns.Add("Fruit")
[void] $DataTable1.Columns.Add("RGB")
# Your CSV content
#"
Fruit,RGB
apple,ff0000
apple,00ff00
kiwi,00ff00
"# | ConvertFrom-Csv | ForEach-Object {
[void] $DataTable1.Rows.Add($_.Fruit, $_.RGB)
}
# Acceptable color values datatable - for your combobox
$DataTable2 = New-Object System.Data.DataTable
[void] $DataTable2.Columns.Add("RGB")
[void] $DataTable2.Columns.Add("Color")
# Manually add rows. You can programmatically add the rows as well
[void] $DataTable2.Rows.Add("ff0000", "red")
[void] $DataTable2.Rows.Add("00ff00", "green")
[void] $DataTable2.Rows.Add("0000ff", "blue")
# Form
$Form = New-Object System.Windows.Forms.Form
$Form.Size = New-Object System.Drawing.Size(500,500)
$Form.StartPosition = "CenterScreen"
# Form event handlers
$Form.Add_Shown({
$Form.Activate()
})
# Datagridview
$DGV = New-Object System.Windows.Forms.DataGridView
$DGV.Anchor = [System.Windows.Forms.AnchorStyles]::Right -bor [System.Windows.Forms.AnchorStyles]::Bottom -bor [System.Windows.Forms.AnchorStyles]::Left -bor [System.Windows.Forms.AnchorStyles]::Top
$DGV.Location = New-Object System.Drawing.Size(0,0)
$DGV.Size = New-Object System.Drawing.Size(480,400)
$DGV.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",10,0,3,1)
$DGV.BackgroundColor = "#ffffffff"
$DGV.BorderStyle = "Fixed3D"
$DGV.AlternatingRowsDefaultCellStyle.BackColor = "#ffe6e6e6"
$DGV.AutoSizeColumnsMode = [System.Windows.Forms.DataGridViewAutoSizeColumnsMode]::Fill
$DGV.AutoSizeRowsMode = [System.Windows.Forms.DataGridViewAutoSizeRowsMode]::AllCells
$DGV.SelectionMode = [System.Windows.Forms.DataGridViewSelectionMode]::FullRowSelect
$DGV.ClipboardCopyMode = "EnableWithoutHeaderText"
$DGV.AllowUserToOrderColumns = $True
$DGV.DataSource = $DataTable1
$DGV.AutoGenerateColumns = $False
$Form.Controls.Add($DGV)
# Datagridview columns
$Column1 = New-Object System.Windows.Forms.DataGridViewTextBoxColumn
$Column1.Name = "Fruit"
$Column1.HeaderText = "Fruit"
$Column1.DataPropertyName = "Fruit"
$Column1.AutoSizeMode = "Fill"
$Column2 = New-Object System.Windows.Forms.DataGridViewComboBoxColumn
$Column2.Name = "Color"
$Column2.HeaderText = "Color"
$Column2.DataSource = $DataTable2
$Column2.ValueMember = "RGB"
$Column2.DisplayMember = "Color"
$Column2.DataPropertyName = "RGB"
$DGV.Columns.AddRange($Column1, $Column2)
# Button to export data
$Button = New-Object System.Windows.Forms.Button
$Button.Anchor = [System.Windows.Forms.AnchorStyles]::Left -bor [System.Windows.Forms.AnchorStyles]::Bottom
$Button.Location = New-Object System.Drawing.Size(10,420)
$Button.Text = "Export"
$Form.Controls.Add($Button)
# Button event handlers
$Button.Add_Click({
$DataTable1 | Out-GridView # do what you want
})
# Show form
[void] $Form.ShowDialog()

Switch statement produces incorrect result

I'm creating a script for our support department and interns. I have a working script but wanted to use a GUI to it a bit easier for our interns. At this moment I'm pulling my hair out right now, I've copied the function below and and would like to have the value of $task1_exec. But when I try to put the return $Result in a variable the $Task1 variable is printed not the $Task1_exec one.
$FormTitle = "Formtitle"
$ScriptPath = $(get-location).Path;
$task1 = "Task 1"
$task1_exec = "Perform task 1"
$task2 = "Task 2"
$task2_exec = "Perform task 2"
$task3 = "Task 3"
$task3_exec = "Perform task 3"
$task4 = "Task 4"
$task4_exec = "Perform task 4"
function Prompt-SelectionList
{
Param(
[Parameter(Position=0,Mandatory=$true)][string]$Description,
[Parameter(Position=1,Mandatory=$true)][string[]]$List
)
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
$Form = New-Object System.Windows.Forms.Form
$Form.Text = $FormTitle
$Form.Size = New-Object System.Drawing.Size(500,450) #(300,200)
$Form.StartPosition = "CenterScreen"
$btnOK = New-Object System.Windows.Forms.Button
$btnOK.Location = New-Object System.Drawing.Size(125,375)
$btnOK.Size = New-Object System.Drawing.Size(125,25)
$btnOK.Text = "Run..."
$Form.Controls.Add($btnOK)
$btnCancel = New-Object System.Windows.Forms.Button
$btnCancel.Location = New-Object System.Drawing.Size(250,375)
$btnCancel.Size = New-Object System.Drawing.Size(125,25)
$btnCancel.Text = "Exit"
$btnCancel.Add_Click({ $script:Result = $null; $Form.Close() })
$Form.Controls.Add($btnCancel)
$Label = New-Object System.Windows.Forms.Label
$Label.Location = New-Object System.Drawing.Size(10,20)
$Label.Size = New-Object System.Drawing.Size(480,20)
$Label.Text = $Description
$Form.Controls.Add($Label)
$ListBox = New-Object System.Windows.Forms.ListBox
$ListBox.Location = New-Object System.Drawing.Size(10,40)
$ListBox.Size = New-Object System.Drawing.Size(460,330)
$List | ForEach-Object { [void] $ListBox.Items.Add($_) }
$Form.Controls.Add($ListBox)
$Form.KeyPreview = $True
$Form.Add_KeyDown({ if ($_.KeyCode -eq "Enter") { $script:Result = $ListBox.SelectedItem; $Form.Close() }})
$Form.Add_KeyDown({ if ($_.KeyCode -eq "Escape") { $script:Result = $null; $Form.Close() }})
$btnOK.Add_Click({ $script:Result = $ListBox.SelectedItem; $Form.Close() })
$Form.Topmost = $True
$Form.Add_Shown({ $Form.Activate() })
[void] $Form.ShowDialog()
return $Result
}
function Do-PromptTask
{
switch -wildcard (Prompt-SelectionList "Chose task to run:" #($task1,$task2,$task3,$task4))
{
$task1{$task1_exec}
$task2{$task2_exec}
$Task3{$task3_exec}
$Task4{$task4_exec}
""{Exit} #End Selection (cancel selected)
# "*"{Do-PromptTask} #Keep prompting until "cancel" selected
}
}
Do-PromptTask
My wish is that I could return $task1_exec to a variable so when Do-PromptTask is finished the return can be used to call another script
. ".\Bin\$Result.ps1"
It looks like you're on the right track.
Let's pretend I run Do-PromptTask, chose Task 1, and click Run...
The $result variable from Prompt-SelectionList is passed back to the Switch statement and is out of scope at this point. The switch is doing its job and matching the conditional which then prints $task1_exec, but $result is of no use at this point. If you want to store $task1_exec as a variable, you'd need to set something equal to it. However, I will say you could just act on it in the switch statement without storing it in a variable, if that makes sense.
Less code approach...
function Do-PromptTask
{
switch -wildcard (Prompt-SelectionList "Chose task to run:" #($task1,$task2,$task3,$task4))
{
$task1{Invoke-Expression $task1_exec}
$task2{Invoke-Expression $task2_exec}
$Task3{Invoke-Expression $task3_exec}
$Task4{Invoke-Expression $task4_exec}
""{Exit} #End Selection (cancel selected)
# "*"{Do-PromptTask} #Keep prompting until "cancel" selected
}
}
If you're set on storing the variable, you could do something like this...
function Do-PromptTask
{
switch -wildcard (Prompt-SelectionList "Chose task to run:" #($task1,$task2,$task3,$task4))
{
$task1{$task_result = $task1_exec}
$task2{$task_result = $task2_exec}
$Task3{$task_result = $task3_exec}
$Task4{$task_result = $task4_exec}
""{Exit} #End Selection (cancel selected)
# "*"{Do-PromptTask} #Keep prompting until "cancel" selected
}
Invoke-Expression $task_result
}

Resources