Unable to get the selected item directly - powershell

I just learned about powershell gui programming. The following code can be executed successfully, but the result of the execution is not the text of the item in the list.
like this:
#{Name=a1; Status=True}
#{Name=a2; Status=False}
I need to output the text of the item directly.
a1
a2
I tried a lot of methods but no results
Thanks in advance
function Show-7_psf {
[void][reflection.assembly]::Load('System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')
[void][reflection.assembly]::Load('System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089')
[System.Windows.Forms.Application]::EnableVisualStyles()
$form1 = New-Object 'System.Windows.Forms.Form'
$buttonOk = New-Object 'System.Windows.Forms.Button'
$checkedlistbox1 = New-Object 'System.Windows.Forms.CheckedListBox'
$InitialFormWindowState = New-Object 'System.Windows.Forms.FormWindowState'
$csvtxt = #'
Name,Status
a1,True
a2,False
a3,False
'#
$form1_Load = {
$csv = ConvertFrom-Csv $csvtxt
$checkedlistbox1.DataSource = [System.Collections.ArrayList]$csv
$checkedlistbox1.DisplayMember = 'Name'
for ($i = 0; $i -lt $checkedlistbox1.Items.Count; $i++)
{
$state = if ($checkedlistbox1.Items[$i].Status -eq 'True') { $true }
else { $false }
$checkedlistbox1.SetItemChecked($i, $state)
}
}
$buttonOk_Click = {
$checkedlistbox1.CheckedItems | Write-Host
}
$Form_StateCorrection_Load=
{
#Correct the initial state of the form to prevent the .Net maximized form issue
$form1.WindowState = $InitialFormWindowState
}
$Form_Cleanup_FormClosed=
{
#Remove all event handlers from the controls
try
{
$buttonOk.remove_Click($buttonOk_Click)
$form1.remove_Load($form1_Load)
$form1.remove_Load($Form_StateCorrection_Load)
$form1.remove_FormClosed($Form_Cleanup_FormClosed)
}
catch { Out-Null <# Prevent PSScriptAnalyzer warning #> }
}
$form1.SuspendLayout()
$form1.Controls.Add($buttonOk)
$form1.Controls.Add($checkedlistbox1)
$form1.AutoScaleDimensions = '6, 13'
$form1.AutoScaleMode = 'Font'
$form1.ClientSize = '482, 262'
$form1.Name = 'form1'
$form1.StartPosition = 'CenterScreen'
$form1.Text = 'Form'
$form1.add_Load($form1_Load)
$buttonOk.Location = '357, 199'
$buttonOk.Name = 'buttonOk'
$buttonOk.Size = '67, 25'
$buttonOk.TabIndex = 1
$buttonOk.Text = 'OK'
$buttonOk.UseCompatibleTextRendering = $True
$buttonOk.UseVisualStyleBackColor = $True
$buttonOk.add_Click($buttonOk_Click)
$checkedlistbox1.CheckOnClick = $True
$checkedlistbox1.FormattingEnabled = $True
$checkedlistbox1.Location = '49, 30'
$checkedlistbox1.Name = 'checkedlistbox1'
$checkedlistbox1.Size = '177, 184'
$checkedlistbox1.TabIndex = 0
$checkedlistbox1.UseCompatibleTextRendering = $True
$form1.ResumeLayout()
#Save the initial state of the form
$InitialFormWindowState = $form1.WindowState
#Init the OnLoad event to correct the initial state of the form
$form1.add_Load($Form_StateCorrection_Load)
#Clean up the control events
$form1.add_FormClosed($Form_Cleanup_FormClosed)
#Show the Form
return $form1.ShowDialog()
}
Show-7_psf | Out-Null

Change this line
$checkedlistbox1.CheckedItems | Write-Host
To
$checkedlistbox1.CheckedItems.Name | Write-Host
This is because you are calling the object in the $csv array but not selecting the Property so you are returning the entire object in the array.

If you want any other property then replace with name
$buttonOk_Click = {
$checkedlistbox1.CheckedItems | Where-Object { $_."Name" | Write-Host }
}

Related

Populate ComboBox2 depending on ComboBox1 selection

Few days of searching and trying multiple options, but nothing is working actually. With the previous code posted.
I've imported all my objects from XAML (all set in variables), I don't know if that would be a problem for that. I don't think since everything else seems to work properly.
I just want my Tab2CBB2 to show values depending on the selection of Tab1CBB1. Anyone could help ? (I haven't paste the entire code, neither the paths but you can probably help me with that). Note that those are two of my multiple tries. Thanks
[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
[xml]$xaml = #" ...
"#
#Read XAML (Parse it)
$reader=(New-Object System.Xml.XmlNodeReader $XAML)
$Window=[Windows.Markup.XamlReader]::Load( $reader )
$listQA14 = Get-ChildItem $pathQA14 -name
$listQA15 = Get-ChildItem $pathQA15 -name
$listDBQA = Get-ChildItem $pathDBQA -name
$Tab1CBB1_SelectedIndexChanged= {
$Tab1CBB2.Items.Clear() # Clear the list
$Tab1CBB2.Text = $null # Clear the current entry
Switch ($Tab1CBB1.Text) {
'QA14' {
$ListQA14 | ForEach { $Tab1CBB2.Items.Add($_) }
}
'QA15' {
$ListQA15 | ForEach { $Tab1CBB2.Items.Add($_) }
}
'ARIELDBQA' {
$ListDBQA | ForEach { $Tab1CBB2.Items.Add($_) }
}
}
}
$Tab1CBB1.add_SelectedIndexChanged($Tab1CBB1_SelectedIndexChanged)
#Displays the Window
$Window.ShowDialog() | out-null
Here is another option tried :
#ComboBox1------
$ItemsCBB1 = #('ARIELDBQA','QA14','QA15')
foreach ($Item in $ItemsCBB1) {
$Tab1CBB1.Items.Add($Item)
}
#ComboBox2-------
if ($Tab1CBB1.SelectedItem -eq 'QA14') {
$Tab1CBB2.Items.Clear()
foreach ($Serie in $listQA14) {
$Tab1CBB2.Items.Add($Serie)
}
}
elseif ($Tab1CBB1.SelectedItem -eq 'QA15') {
$Tab1CBB2.Items.Clear()
foreach ($Serie in $listQA15) {
$Tab1CBB2.Items.Add($Serie)
}
}
elseif ($Tab1CBB1.SelectedItem -eq 'listDBQA') {
$Tab1CBB2.Items.Clear()
foreach ($Serie in $listDBQA) {
$Tab1CBB2.Items.Add($Serie)
}
}
Tried this also : $Selection = $Tab1CBB1.SelectedItem.ToString()
Variable $selection put after 'if', but not working
Note that when I indicate what the current selection would be, it is working properly. The problem seems to come from 'recording' the selection a the time of clicking... Thnaks !
Basically, all you have to do is inside the $Tab1CBB1_SelectedIndexChanged scriptblock use the various lists with script scoping.
Without that, the variables are unknown inside the script block.
$Tab1CBB1_SelectedIndexChanged = {
$Tab1CBB2.Items.Clear() # Clear the list
$Tab1CBB2.Text = $null # Clear the current entry
switch ($Tab1CBB1.Text) {
'QA14' { $script:ListQA14 | ForEach-Object { $Tab1CBB2.Items.Add($_) } }
'QA15' { $script:ListQA15 | ForEach-Object { $Tab1CBB2.Items.Add($_) } }
'ARIELDBQA' { $script:ListDBQA | ForEach-Object { $Tab1CBB2.Items.Add($_) } }
}
}
Another method could be to dynamically get the items to enter in the combobox, especially since these are file lists and can change while your form is being used:
$Tab1CBB1_SelectedIndexChanged = {
$Tab1CBB2.Items.Clear() # Clear the list
$Tab1CBB2.Text = $null # Clear the current entry
switch ($Tab1CBB1.Text) {
'QA14' { $path = $script:pathQA14 ; break }
'QA15' { $path = $script:pathQA15 ; break }
'ARIELDBQA' { $path = $script:pathDBQA }
}
Get-ChildItem -Path $path -Name | ForEach-Object { $Tab1CBB2.Items.Add($_) }
}
A simple example of what you seem to be after is something like this.
### Powershell populate ComboBox 2 based on ComboBox 1 Selection
Add-type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
$form1 = New-Object 'System.Windows.Forms.Form'
$labelDoubleClickOnAnyItem = New-Object 'System.Windows.Forms.Label'
$listbox2 = New-Object 'System.Windows.Forms.ListBox'
$listbox1 = New-Object 'System.Windows.Forms.ListBox'
$buttonOK = New-Object 'System.Windows.Forms.Button'
$form1_Load={
$items=1..9 |
ForEach-Object {"List item $_"}
$listbox1.Items.AddRange($items)
}
$listbox1_MouseDoubleClick=[System.Windows.Forms.MouseEventHandler]{
$listbox2.Items.Add($listbox1.SelectedItem)
$listbox1.Items.Remove($listbox1.SelectedItem)
}
$listbox2_MouseDoubleClick=[System.Windows.Forms.MouseEventHandler]{
$listbox1.Items.Add($listbox2.SelectedItem)
$listbox2.Items.Remove($listbox2.SelectedItem)
}
$form1.Controls.Add($labelDoubleClickOnAnyItem)
$form1.Controls.Add($listbox2)
$form1.Controls.Add($listbox1)
$form1.Controls.Add($buttonOK)
$form1.AcceptButton = $buttonOK
$form1.ClientSize = '378, 388'
$form1.FormBorderStyle = 'FixedDialog'
$form1.MaximizeBox = $False
$form1.MinimizeBox = $False
$form1.Name = 'form1'
$form1.StartPosition = 'CenterScreen'
$form1.Text = 'Form'
$form1.add_Load($form1_Load)
$labelDoubleClickOnAnyItem.Font = 'Microsoft Sans Serif, 9.75pt, style=Bold, Italic'
$labelDoubleClickOnAnyItem.Location = '13, 13'
$labelDoubleClickOnAnyItem.Name = 'labelDoubleClickOnAnyItem'
$labelDoubleClickOnAnyItem.Size = '353, 41'
$labelDoubleClickOnAnyItem.TabIndex = 3
$labelDoubleClickOnAnyItem.Text = 'Double click on any item to move it from one box to the other.'
$listbox2.FormattingEnabled = $True
$listbox2.Location = '200, 67'
$listbox2.Name = 'listbox2'
$listbox2.Size = '166, 277'
$listbox2.Sorted = $True
$listbox2.TabIndex = 2
$listbox2.add_MouseDoubleClick($listbox2_MouseDoubleClick)
$listbox1.FormattingEnabled = $True
$listbox1.Location = '12, 67'
$listbox1.Name = 'listbox1'
$listbox1.Size = '167, 277'
$listbox1.Sorted = $True
$listbox1.TabIndex = 1
$listbox1.add_MouseDoubleClick($listbox1_MouseDoubleClick)
$buttonOK.Anchor = 'Bottom, Right'
$buttonOK.DialogResult = 'OK'
$buttonOK.Location = '291, 353'
$buttonOK.Name = 'buttonOK'
$buttonOK.Size = '75, 23'
$buttonOK.TabIndex = 0
$buttonOK.Text = '&OK'
$form1.ShowDialog()
Or even this using just the ComboBox elements
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
$Form = New-Object system.Windows.Forms.Form
$Form.ClientSize = New-Object System.Drawing.Point(498,459)
$Form.text = 'Form'
$Form.TopMost = $false
$Form.StartPosition = 'CenterScreen'
$ComboBox1 = New-Object system.Windows.Forms.ComboBox
$ComboBox1.text = ''
$ComboBox1.width = 216
$ComboBox1.height = 75
#('ComboxItem1','ComboxItem2','ComboxItem3') |
ForEach-Object {[void] $ComboBox1.Items.Add($_)}
$ComboBox1.location = New-Object System.Drawing.Point(31,41)
$ComboBox1.Font = New-Object System.Drawing.Font('Microsoft Sans Serif',10)
$ComboBox2 = New-Object system.Windows.Forms.ComboBox
$ComboBox2.text = ''
$ComboBox2.width = 213
$ComboBox2.height = 38
$ComboBox2.location = New-Object System.Drawing.Point(32,73)
$ComboBox2.Font = New-Object System.Drawing.Font('Microsoft Sans Serif',10)
Function Add-ItemToComboBox2
{
$ComboBox2.Items.Add($ComboBox1.SelectedItem)
$ComboBox2.Refresh()
}
$Form.controls.AddRange(
#(
$ComboBox1,
$ComboBox2
)
)
$ComboBox1.Add_SelectedIndexChanged({ Add-ItemToComboBox2 })
[void]$Form.ShowDialog()
You have not stated what UX/UI tool you are using to design and implement your
GUI. Yet, hard coding is also just a challenge. So consider using one of these for your UX/UI effort. Your UX/UI should just work, whether you have PowerShell code behind it (or any other language). Your PowerShell code should just work, regardless of the UX/UI that may be implemented. Your UX/UI code should be separate from your ops code. You call your ops code from the UX/UI.
Free:
https://poshgui.com
https://www.youtube.com/results?search_query=poshgui
https://visualstudio.microsoft.com/vs/community
Be sure to thoroughly read the licensing agreement for VS.
https://www.youtube.com/results?search_query=vs+2019+community+winforms
Purchase
https://ironmansoftware.com/psscriptpad
https://www.youtube.com/results?search_query=psscriptpad
https://ironmansoftware.com/powershell-pro-tools
https://www.youtube.com/results?search_query=powershell-pro-tools
https://www.sapien.com/software/powershell_studio
https://www.youtube.com/results?search_query=Sapien%27s+powershell+studio++winforms
https://visualstudio.microsoft.com/vs
https://www.youtube.com/results?search_query=vs+2019+community+winforms

PowerShell Form Data Output To JSON Format

The following GIF image is an example of a dialog written use the C# programming language, which contains four controls!
Now, I want to use PowerShell to achieve the same functionality, I made the following design (such as the first dialog in the GIF picture):
The first control, the ID name is Input
The second control, the ID name is MultipleSelect
The third control, the ID name is InlineRadioOption
The fourth control, the ID name is Checkbox
When I click the OK button, I want to output the values ​​of all the controls to a JSON format object, for example: $CustomDialogResults
Later, I can get the value of each control in the following way (such as the second message box in the GIF image):
$CustomDialogResults.Input
$CustomDialogResults.MultipleSelect
$CustomDialogResults.InlineRadioOption
$CustomDialogResults.Checkbox
I want to know how to express objects in JSON format?
function Show-dialog_psf {
[void][reflection.assembly]::Load('System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089')
[void][reflection.assembly]::Load('System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')
#endregion Import Assemblies
#----------------------------------------------
#region Generated Form Objects
#----------------------------------------------
[System.Windows.Forms.Application]::EnableVisualStyles()
$form1 = New-Object 'System.Windows.Forms.Form'
$labelInlinRadios = New-Object 'System.Windows.Forms.Label'
$panel1 = New-Object 'System.Windows.Forms.Panel'
$radiobuttonRadioOption3 = New-Object 'System.Windows.Forms.RadioButton'
$radiobuttonRadioOption1 = New-Object 'System.Windows.Forms.RadioButton'
$radiobuttonRadioOption2 = New-Object 'System.Windows.Forms.RadioButton'
$Checkbox = New-Object 'System.Windows.Forms.CheckBox'
$MultipleSelect = New-Object 'System.Windows.Forms.CheckedListBox'
$labelMultipleSelect = New-Object 'System.Windows.Forms.Label'
$input = New-Object 'System.Windows.Forms.TextBox'
$labelInput = New-Object 'System.Windows.Forms.Label'
$buttonOK = New-Object 'System.Windows.Forms.Button'
$InitialFormWindowState = New-Object 'System.Windows.Forms.FormWindowState'
#endregion Generated Form Objects
#----------------------------------------------
# User Generated Script
#----------------------------------------------
$form1_Load = {
#TODO: Initialize Form Controls here
}
$buttonOK_Click = {
$CustomDialogResults = #{
#$CustomDialogResults.Input,
#$CustomDialogResults.MultipleSelect,
#$CustomDialogResults.InlineRadioOption,
#$CustomDialogResults.Checkbox,
}
[void][System.Windows.Forms.MessageBox]::Show($CustomDialogResults, 'Title') # Casting the method to [void] suppresses the output.
}
# --End User Generated Script--
#----------------------------------------------
#region Generated Events
#----------------------------------------------
$Form_StateCorrection_Load=
{
#Correct the initial state of the form to prevent the .Net maximized form issue
$form1.WindowState = $InitialFormWindowState
}
$Form_Cleanup_FormClosed=
{
#Remove all event handlers from the controls
try
{
$buttonOK.remove_Click($buttonOK_Click)
$form1.remove_Load($form1_Load)
$form1.remove_Load($Form_StateCorrection_Load)
$form1.remove_FormClosed($Form_Cleanup_FormClosed)
}
catch { Out-Null <# Prevent PSScriptAnalyzer warning #> }
}
#endregion Generated Events
#----------------------------------------------
#region Generated Form Code
#----------------------------------------------
$form1.SuspendLayout()
$panel1.SuspendLayout()
#
# form1
#
$form1.Controls.Add($labelInlinRadios)
$form1.Controls.Add($panel1)
$form1.Controls.Add($Checkbox)
$form1.Controls.Add($MultipleSelect)
$form1.Controls.Add($labelMultipleSelect)
$form1.Controls.Add($input)
$form1.Controls.Add($labelInput)
$form1.Controls.Add($buttonOK)
$form1.AcceptButton = $buttonOK
$form1.AutoScaleDimensions = '6, 13'
$form1.AutoScaleMode = 'Font'
$form1.ClientSize = '436, 288'
$form1.FormBorderStyle = 'FixedDialog'
$form1.MaximizeBox = $False
$form1.MinimizeBox = $False
$form1.Name = 'form1'
$form1.StartPosition = 'CenterScreen'
$form1.Text = 'Form'
$form1.add_Load($form1_Load)
#
# labelInlinRadios
#
$labelInlinRadios.AutoSize = $True
$labelInlinRadios.Location = '21, 172'
$labelInlinRadios.Name = 'labelInlinRadios'
$labelInlinRadios.Size = '63, 17'
$labelInlinRadios.TabIndex = 10
$labelInlinRadios.Text = 'Inlin Radios'
$labelInlinRadios.UseCompatibleTextRendering = $True
#
# panel1
#
$panel1.Controls.Add($radiobuttonRadioOption3)
$panel1.Controls.Add($radiobuttonRadioOption1)
$panel1.Controls.Add($radiobuttonRadioOption2)
$panel1.AutoSize = $True
$panel1.Location = '95, 162'
$panel1.Name = 'panel1'
$panel1.Size = '329, 32'
$panel1.TabIndex = 9
#
# radiobuttonRadioOption3
#
$radiobuttonRadioOption3.Location = '217, 5'
$radiobuttonRadioOption3.Name = 'radiobuttonRadioOption3'
$radiobuttonRadioOption3.Size = '105, 24'
$radiobuttonRadioOption3.TabIndex = 7
$radiobuttonRadioOption3.TabStop = $True
$radiobuttonRadioOption3.Text = 'Radio option3'
$radiobuttonRadioOption3.UseCompatibleTextRendering = $True
$radiobuttonRadioOption3.UseVisualStyleBackColor = $True
#
# radiobuttonRadioOption1
#
$radiobuttonRadioOption1.Location = '7, 4'
$radiobuttonRadioOption1.Name = 'radiobuttonRadioOption1'
$radiobuttonRadioOption1.Size = '105, 24'
$radiobuttonRadioOption1.TabIndex = 5
$radiobuttonRadioOption1.TabStop = $True
$radiobuttonRadioOption1.Text = 'Radio option1'
$radiobuttonRadioOption1.UseCompatibleTextRendering = $True
$radiobuttonRadioOption1.UseVisualStyleBackColor = $True
#
# radiobuttonRadioOption2
#
$radiobuttonRadioOption2.Location = '112, 4'
$radiobuttonRadioOption2.Name = 'radiobuttonRadioOption2'
$radiobuttonRadioOption2.Size = '105, 24'
$radiobuttonRadioOption2.TabIndex = 6
$radiobuttonRadioOption2.TabStop = $True
$radiobuttonRadioOption2.Text = 'Radio option2'
$radiobuttonRadioOption2.UseCompatibleTextRendering = $True
$radiobuttonRadioOption2.UseVisualStyleBackColor = $True
#
# Checkbox
#
$Checkbox.Location = '102, 200'
$Checkbox.Name = 'Checkbox'
$Checkbox.Size = '104, 24'
$Checkbox.TabIndex = 8
$Checkbox.Text = 'checkbox1'
$Checkbox.UseCompatibleTextRendering = $True
$Checkbox.UseVisualStyleBackColor = $True
#
# MultipleSelect
#
$MultipleSelect.CheckOnClick = $True
$MultipleSelect.FormattingEnabled = $True
[void]$MultipleSelect.Items.Add('Multiple Select option1')
[void]$MultipleSelect.Items.Add('Multiple Select option2')
[void]$MultipleSelect.Items.Add('Multiple Select option3')
$MultipleSelect.Location = '121, 68'
$MultipleSelect.Name = 'MultipleSelect'
$MultipleSelect.Size = '277, 79'
$MultipleSelect.TabIndex = 4
$MultipleSelect.UseCompatibleTextRendering = $True
#
# labelMultipleSelect
#
$labelMultipleSelect.AutoSize = $True
$labelMultipleSelect.Location = '27, 68'
$labelMultipleSelect.Name = 'labelMultipleSelect'
$labelMultipleSelect.Size = '78, 17'
$labelMultipleSelect.TabIndex = 3
$labelMultipleSelect.Text = 'Multiple Select'
$labelMultipleSelect.UseCompatibleTextRendering = $True
#
# input
#
$input.Location = '121, 31'
$input.Name = 'input'
$input.Size = '277, 20'
$input.TabIndex = 2
$input.Text = 'input text'
#
# labelInput
#
$labelInput.AutoSize = $True
$labelInput.Location = '76, 34'
$labelInput.Name = 'labelInput'
$labelInput.Size = '29, 17'
$labelInput.TabIndex = 1
$labelInput.Text = 'Input'
$labelInput.UseCompatibleTextRendering = $True
#
# buttonOK
#
$buttonOK.Anchor = 'Bottom, Right'
$buttonOK.DialogResult = 'OK'
$buttonOK.Location = '349, 253'
$buttonOK.Name = 'buttonOK'
$buttonOK.Size = '75, 23'
$buttonOK.TabIndex = 0
$buttonOK.Text = '&OK'
$buttonOK.UseCompatibleTextRendering = $True
$buttonOK.UseVisualStyleBackColor = $True
$buttonOK.add_Click($buttonOK_Click)
$panel1.ResumeLayout()
$form1.ResumeLayout()
#endregion Generated Form Code
#----------------------------------------------
#Save the initial state of the form
$InitialFormWindowState = $form1.WindowState
#Init the OnLoad event to correct the initial state of the form
$form1.add_Load($Form_StateCorrection_Load)
#Clean up the control events
$form1.add_FormClosed($Form_Cleanup_FormClosed)
#Show the Form
return $form1.ShowDialog()
} #End Function
#Call the form
Show-dialog_psf | Out-Null
Change your buttonOk click function to get desire output :
Note : This is the sample json, you have yo replace the hard-coded string with your actual values | objects.
$buttonOK_Click = {
$CustomDialogResults = #{}
$CustomDialogResults.Add("Input",$txtinput.Text)
$CustomDialogResults.Add("MultipleSelect",$MultipleSelect.CheckedItems)
$CustomDialogResults.Add("Checkbox", $Checkbox.Checked)
$selectedradio = $null ;
switch($True)
{
$($radiobuttonRadioOption1.Checked){
$selectedradio = $radiobuttonRadioOption1.Text ;
}
$($radiobuttonRadioOption2.Checked){
$selectedradio = $radiobuttonRadioOption2.Text ;
}
$($radiobuttonRadioOption3.Checked){
$selectedradio = $radiobuttonRadioOption3.Text ;
}
}
$CustomDialogResults.Add("InlineRadioOption",$selectedradio)
$temp = ConvertTo-Json -InputObject $CustomDialogResults
[void][System.Windows.Forms.MessageBox]::Show($temp, 'Title')
}
I would do something like this in ur ButtonOk_click eventhandler.
function Get-RadioButtonCheck
{
#if-else logic
#returns which Radio button is checked
$CheckedRadioButton = "RadioButton1" #as an example
Return $CheckedRadioButton
}
$CustomDialogResults = [PSCustomObject]#{
Input = $($input.Text)
MultipleSelect = $($MultipleSelect.SelectedItems)
InlineRadioOption = Get-RadioButtonCheck
Checkbox = $($Checkbox.Checked)
}
$JSONdata = $CustomDialogResults | ConvertTo-Json
#Now you can output this $JSONdata to a file or text box or even a Messagebox like u are already doing

DataGridView. Run Job while entering new row parallel

The script included is to check the replication and repair for each Server that I add. The goal I have in mind is for it to automatically check the connection of each computer as I add them as well as check the uptime.
The current issue I'm having is that it will delay to check the uptime before it allows me to input my next computer.
As you can see in my script I'm trying to use a start-job which is not working at all for me as it says the 'ComputerName' is null, but the ComputerName is set in the Get-Uptime function.
I may be going about this all wrong. Any help would be great!!
function Check-Replication {
#----------------------------------------------
#region Import the Assemblies
#----------------------------------------------
[void][Reflection.Assembly]::Load('System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089')
[void][Reflection.Assembly]::Load('System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089')
[void][Reflection.Assembly]::Load('System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')
[void][Reflection.Assembly]::Load('System.DirectoryServices, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')
[void][Reflection.Assembly]::Load('System.ServiceProcess, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')
#endregion Import Assemblies
$base64Image = "iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAQAAADYWf5HAAAABGdBTUEAALGPC/xhBQAAAAJiS0dEAP+Hj8y/AAAACXBIWXMAAWG3AAFhtwFW7IyrAAAAB3RJTUUH4goDDxY48JvtEgAAAg9JREFUKM9NkT9MU1EUxn/33kf/APVPYQGaYImLYQAikU6kidFoWBwYjLgw6SZxkLhgnExc0A1ZHDC6uOmMDQ5KLCYuqINxoFgq2Ce0fbx/912GvhDOlzN9X77znXMEAFyhL7Uxmbl9vjjQn1ahrv35Vdp7NbxWc1eJaxFJIX9h+UZ9yZTMF/PVlM1Hs2Jm6yPLl/KwCIinPGZwxHsxPnGTXhQSgSEi4oB3rK7LO1vfFlA75Ib2X54rTJNFIBGAISLE0MdOrjo69GHDlteT9nxXYZQMEWBOQNPBGJmCPX81qZzL/kIuPUwPHVjxSIiI0Pj4/MXOV8pWa6Yzm0XFhIzXimLAGTqzrRkrKnbThSYgxELEwoiQkJCATrppFi09kCKJwSNJgEEgMBhCAjwCEqTQA5ZW7SME+AiiE24BPgaJQiuptI5zaCLMcRs0bSZEaSm3D/HwCdBodCzS6Dibh4valrLUoEGLQ1x8guPoPh6HODRpQkkNOs5UIp0mgUIAEZoQH5cm+/yjym6965GarXwfdC8msOJfhrFPW1Sjgl65tqRsfXrz/4SXkxg0IR4uDg322aPGFo3PPfc399QD3ti95dZYKxfg4+LQ4gCbXapUaKwn7/78MYeA59yjkK8/NNPpsxlSKDQuTRxbvs0++fT7GXOI9g+n6E+VJw9umaLJhcrSoiJKp16Pr1Xd9wAcAYNiEWcBi781AAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE4LTEwLTAzVDE1OjIyOjU2LTA0OjAwISeC9gAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxOC0xMC0wM1QxNToyMjo1Ni0wNDowMFB6OkoAAAAASUVORK5CYII="
$imageBytes = [Convert]::FromBase64String($base64Image)
$memStream = New-Object IO.MemoryStream($imageBytes, 0, $imageBytes.Length)
$memStream.Write($imageBytes, 0, $imageBytes.Length);
$imageGrey = [System.Drawing.Bitmap]::FromStream($memStream, $true)
$base64Image = "iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsSAAALEgHS3X78AAAAB3RJTUUH4goDDxstKOh3tAAABJVJREFUOMtVlNtvVFUUxn/r3M8w7bSddloYWkpALlqoEBJ9IIQoSUUTEYj6B8CLMSbySOKTvtQYnlDf1ITggwHFiEAIl4CVxPBAAhQKIVwCpXTaTjuXM3PmXOZsH6aA7uTbe2Vl5Vt7rXxrCf85V69epVKpkMvlejVNW2saZtq2HU3XdA+gmcRdYRRKGIalJEkm6vX6M8uy1ObNm19wyHPj2rVrJEliua671bGdnFetPbwwdm7g1v3xVTPFmXbTMLUlqXRheM3wo5HtI0U3neoJgqAahuGYpmn+8PDwS8Lx8XGSJGlzHPtz07SWnT5/ev63yye2VbTqJiujp6wlpogIoR+rZjXxcnbvnd1bd13Z/uZ2I4zDsu/7h3RdXxgaGkKuX79Oo9EwM5n2L0zD+uT4mWP1Hy791FfL1my1VBGkAiIjBAEjNnHqDvqMTrbWGe/fvr/47rb39DAKf/Y876Bpmr5hGAau6+7WNf3T38+e0L85e2h5qb+kq/6EZrYJ7SB2qzMqBKoK3dF5NjlljJ79utc0zOCtN97eZ9nWDdd1fzR83+9LuakDE/fuZL87972aWzYrskpQeZBuDdIKLEAJEivwhKRdoeyEyeYk354/bK/Mr7SX9/Z/Vi6VL2oi8m4QhJuOXfiVh9YjkRUtMpYCvQp6gRyQU5AD1QcsVUgeZFC4pSb4458/iaJoSET2akqpXZNTj+0rD/9G9SXQI0g3SBeoTlDtQBuojEAGJAN0AVmgB5KehL8eXGa2OGskSfK+EUfx6/cfP6DQfIZ0AG0K0kAaJAU4gC6AAmNRY3ErCW2tJE8LT5mcfUrKTW3U6vV6R6FYIDBDcARsWj0zQAxpkT2HAZiAqVAmYCtwFL40KJaL+HU/ozUaDYmiCEFQAiIvJ0ct3uqF9XIe5LlDtcQcxTG+74vWTJrltJPGbtrQWJRG1CpLxQrVBEkUkihoKogXEQEhSAAOLq7h0Gw2K5pK1I2u9i5yeg7KIFXAE1Qd8IEGECyiAcoHaoKqAR6oMuTtPGkrTaKSW5ph6KeWpNqjDd0b0GcENStQBJkHKYFUgEVIGaQksNCKUXOgF3U29W1GFz0xDOOUls12n7Rt8+aWFVsYjAZRTxLUlIJpoADMPoe03gIwrWAKeKxYr69nY+8QmsjdTCZzXM/n85XBFSuCZpS80yEdxuPJJ9TCKpIIhK2yVX3xp0VgRmAK5KGivzTAx2s+JJvqjjq7Or86evToGX10dJSBgYG7Cwvz3SbmlqVmn3hzVYJKiBEYaDUdKYFWFIw5E6dg4046rA3W8MGqPfSlelVHR8eRda+uGx3eOBwKwKVLl2hra+u6ffv2l4Xpwr6F6rxzv/SAp/EkDScAp6UPLdBwohT97gCr21eRttJRNps9svqV1Qc9z5vduXPnywU7NjZGJpNxb9y8+dH83NyBeq021IgC3U8CYmJEwBILx3AxdbPpOs69bHf28Lq1646Uy2Vvx44d/9/YAIVCgVwux4WLFwann03v9TxvTxAEr8VxnBEEXdcrlmVNpNvSJ3t6en4ZGRm5PzU1pfL5/AuOfwFWfAyFldyKLAAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxOC0xMC0wM1QxNToyNzo0NS0wNDowMDpMU7EAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTgtMTAtMDNUMTU6Mjc6NDUtMDQ6MDBLEesNAAAAAElFTkSuQmCC"
$imageBytes = [Convert]::FromBase64String($base64Image)
$memStream = New-Object IO.MemoryStream($imageBytes, 0, $imageBytes.Length)
$memStream.Write($imageBytes, 0, $imageBytes.Length);
$imageGreen = [System.Drawing.Bitmap]::FromStream($memStream, $true)
$base64Image = "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"
$imageBytes = [Convert]::FromBase64String($base64Image)
$memStream = New-Object IO.MemoryStream($imageBytes, 0, $imageBytes.Length)
$memStream.Write($imageBytes, 0, $imageBytes.Length);
$imageRed = [System.Drawing.Bitmap]::FromStream($memStream, $true)
#----------------------------------------------
#region Generated Form Objects
#----------------------------------------------
[System.Windows.Forms.Application]::EnableVisualStyles()
$form1 = New-Object 'System.Windows.Forms.Form'
$labelTypeEachComputerName = New-Object 'System.Windows.Forms.Label'
$textbox1 = New-Object 'System.Windows.Forms.TextBox'
$datagridview1 = New-Object 'System.Windows.Forms.DataGridView'
$buttonRun = New-Object 'System.Windows.Forms.Button'
$Online = New-Object 'System.Windows.Forms.DataGridViewImageColumn'
$Uptime = New-Object 'System.Windows.Forms.DataGridViewTextBoxColumn'
$Computer = New-Object 'System.Windows.Forms.DataGridViewTextBoxColumn'
$Status = New-Object 'System.Windows.Forms.DataGridViewTextBoxColumn'
$InitialFormWindowState = New-Object 'System.Windows.Forms.FormWindowState'
#endregion Generated Form Objects
#----------------------------------------------
# Function Get-Uptime
#----------------------------------------------
#region - Get-Uptime
$Uptime1 = {
function Get-Uptime {
Params ($ComputerName)
$global:ComputerName = $row.cells[2].Value
$os = Get-WmiObject win32_operatingsystem -ComputerName $ComputerName -ErrorAction SilentlyContinue
if ($os.LastBootUpTime) {
$uptime = (Get-Date) - $os.ConvertToDateTime($os.LastBootUpTime)
#Write-Output ("Last boot: " + $os.ConvertToDateTime($os.LastBootUpTime) )
Write-Output ("" + $uptime.Days + "d " + $uptime.Hours + "h " + $uptime.Minutes + "m" )
} else {
Write-Warning "Unable to connect to $computername"
}
}
}
#endregion
#----------------------------------------------
# User Generated Script
#----------------------------------------------
$FormEvent_Load = {
}
$textbox1_Validated = {
if ($textbox1.Text -ne "") {
$i = $datagridview1.Rows.Add(1)
$row = $datagridview1.Rows[$i]
$row.SetValues(#($imageGrey,'',$textbox1.Text,'pending'))
$textbox1.Text = ''
$textbox1.Focus()
if ($row.Cells[2].Value -ne "") {
if (Test-Connection -ComputerName $row.cells[2].Value -Count 1 -Quiet) {
$Time = Get-Date
Start-Job -InitializationScript $Uptime1 -scriptblock {(Get-Uptime -ComputerName $args[0])} -Args $row.cells[2].Value |
#Start-Job -InitializationScript $Uptime1 -scriptblock {(Get-Uptime)}|
Wait-Job | Receive-Job
$row.SetValues(#($imageGrey,($Uptime),$row.Cells[2].Value))
#Remove-Job -Name CheckSiteUptime
$Time = Get-date
$row.Cells[0].Value = $imageGreen
} else {
$row.Cells[0].Value = $imageRed}
}
}
}
$buttonRun_Click = {
$datagridview1.Rows | ForEach-Object {
$row = [System.Windows.Forms.DataGridViewRow]$_
$CommandResult = Invoke-Command -ComputerName $row.cells[2].Value -ArgumentList $row -ScriptBlock{
Param($row)
Import-Module Hyper-V
if ((Get-VM -ErrorAction Stop | Where-Object {$_.name -like '*SR*'} | Get-VMReplication -ErrorAction Stop).Replicationhealth -eq 'critical') {
try{
Get-VM -ErrorAction Stop | Where-Object {$_.name -like '*SR*'} | Resume-VMReplication -ErrorAction Stop
if ((Get-VM -ErrorAction Stop | Where-Object {$_.name -like '*SR*'} | Get-VMReplication -ErrorAction Stop).Replicationhealth -eq 'critical') {
throw [System.Exception] "Replicationhealth critical"
}
} catch {
try{
Get-VM -ErrorAction Stop | Where-Object {$_.name -like '*SR*'} | Resume-VMReplication -Resynchronize -ErrorAction Stop
} catch {
return 'FAILED: Resume-VMReplication -Resynchronize'
break
}
return 'Successful: Resume-VMReplication -Resynchronize'
break
}
return 'Successful: Resume-VMReplication'
} else {
return 'Successful: No action replication is NOT critical'
}
}
switch ($CommandResult) {
"FAILED: Resume-VMReplication -Resynchronize" {
$row.Cells | %{$_.Style.BackColor = 'pink'}
$Row.Cells[3].Value = $CommandResult
}
"Successful: Resume-VMReplication -Resynchronize" {
$row.Cells | %{$_.Style.BackColor = 'lightgreen'}
$Row.Cells[3].Value = $CommandResult
}
"Successful: Resume-VMReplication" {
$row.Cells | %{$_.Style.BackColor = 'lightgreen'}
$Row.Cells[3].Value = $CommandResult
}
"Successful: No action replication is NOT critical" {
$row.Cells | %{$_.Style.BackColor = 'lightgreen'}
$Row.Cells[3].Value = $CommandResult
}
}
}
$datagridview1.ReadOnly = $true
}
# --End User Generated Script--
#----------------------------------------------
#region Generated Events
#----------------------------------------------
$Form_StateCorrection_Load = {
#Correct the initial state of the form to prevent the .Net maximized form issue
$form1.WindowState = $InitialFormWindowState
}
$Form_Cleanup_FormClosed = {
#Remove all event handlers from the controls
try {
$textbox1.remove_Validated($textbox1_Validated)
$buttonRun.remove_Click($buttonRun_Click)
$form1.remove_Load($FormEvent_Load)
$form1.remove_Load($Form_StateCorrection_Load)
$form1.remove_FormClosed($Form_Cleanup_FormClosed)
} catch {
Out-Null <# Prevent PSScriptAnalyzer warning #>
}
}
#endregion Generated Events
#----------------------------------------------
#region Generated Form Code
#----------------------------------------------
$form1.SuspendLayout()
#
# form1
#
$form1.Controls.Add($labelTypeEachComputerName)
$form1.Controls.Add($textbox1)
$form1.Controls.Add($datagridview1)
$form1.Controls.Add($buttonRun)
$form1.AutoScaleDimensions = '6, 13'
$form1.AutoScaleMode = 'Font'
$form1.ClientSize = '625, 600'
$form1.FormBorderStyle = 'FixedDialog'
$form1.MaximizeBox = $False
$form1.MinimizeBox = $False
$form1.Name = 'form1'
$form1.StartPosition = 'CenterScreen'
$form1.Text = 'Replication Check'
$form1.add_Load($FormEvent_Load)
#
# labelTypeEachComputerName
#
$labelTypeEachComputerName.Location = '20, 18'
$labelTypeEachComputerName.Name = 'labelTypeEachComputerName'
$labelTypeEachComputerName.Size = '240, 49'
#$labelTypeEachComputerName.TabIndex = 5
$labelTypeEachComputerName.Text = 'Type each computer name ending with a <tab> it will be added to the list. Click run when alll have been added.'
$labelTypeEachComputerName.UseCompatibleTextRendering = $True
#
# textbox1
#
$textbox1.CharacterCasing = 'Upper'
$textbox1.Location = '20, 81'
$textbox1.Name = 'textbox1'
$textbox1.Size = '285, 20'
#$textbox1.TabIndex = 1
$textbox1.add_Validated($textbox1_Validated)
#
# datagridview1
#
$datagridview1.AllowUserToAddRows = $False
$datagridview1.AllowUserToDeleteRows = $False
$datagridview1.AllowUserToResizeColumns = $True
$datagridview1.AllowUserToResizeRows = $False
$datagridview1.ColumnHeadersHeightSizeMode = 'AutoSize'
[void]$datagridview1.Columns.Add($Online)
[void]$datagridview1.Columns.Add($Uptime)
[void]$datagridview1.Columns.Add($Computer)
[void]$datagridview1.Columns.Add($Status)
$datagridview1.columns[0].Width = '40'
$datagridview1.columns[3].Width = '250'
$datagridview1.Location = '20, 113'
$datagridview1.Name = 'datagridview1'
$datagridview1.ReadOnly = $True
$datagridview1.Size = '583, 470'
$datagridview1.TabIndex = 3
$datagridview1.DefaultCellStyle.WrapMode = "True"
#
# buttonRun
#
$buttonRun.Location = '325, 80'
$buttonRun.Name = 'buttonRun'
$buttonRun.Size = '75, 23'
$buttonRun.TabIndex = 2
$buttonRun.TabStop = $False
$buttonRun.Text = 'Run'
$buttonRun.UseCompatibleTextRendering = $True
$buttonRun.UseVisualStyleBackColor = $True
$buttonRun.add_Click($buttonRun_Click)
#
# Online
#
$Online.HeaderText = 'Online'
$Online.Name = 'Online'
$Online.DataPropertyName = 'Online'
#
# Uptime
#
$Uptime.HeaderText = 'Uptime'
$Uptime.Name = 'Uptime'
$Uptime.ReadOnly = $True
#
# Computer
#
$Computer.HeaderText = 'Server'
$Computer.Name = 'Server'
$Computer.ReadOnly = $True
#
# Status
#
$Status.HeaderText = 'Status'
$Status.Name = 'Status'
$Status.ReadOnly = $True
$form1.ResumeLayout()
#endregion Generated Form Code
#----------------------------------------------
#Save the initial state of the form
$InitialFormWindowState = $form1.WindowState
#Init the OnLoad event to correct the initial state of the form
$form1.add_Load($Form_StateCorrection_Load)
#Clean up the control events
$form1.add_FormClosed($Form_Cleanup_FormClosed)
#Show the Form
return $form1.ShowDialog()
} #End Function
#Call the form
Check-Replication | Out-Null
Because PowerShell jobs run in a separate runspace, even declaring a variable as $global: does not make it available inside your job. Instead, you need to pass the value in to your job when you create it.
For example, you could change your code as follows:
...
Function Get-Uptime {
params ($ComputerName)
$global:ComputerName = $ComputerName
...
Start-Job -InitializationScript $Uptime1 -scriptblock {(Get-Uptime -ComputerName $args[0])} -Args $row.cells[2].Value
A similar issue is described here: https://social.technet.microsoft.com/Forums/ie/en-US/5b369c15-d2ad-4ee8-a1fc-3f0ca8df230a/powershell-jobs-and-global-variables?forum=ITCG
Another resource on some options other than PS jobs, which tend to be relatively inefficient: https://randombrainworks.com/2018/01/28/powershell-background-jobs-runspace-jobs-thread-jobs/
Another way around your base issue of de-coupling your form/GUI from your backend code is to use runspaces and a synchronized hashtable. The advantage of this model is that your can have many threads simultaneously performing work and actively updating your form, and instead of passing variables around, you have a single copy and pass references.
This is a great article to get started: https://learn-powershell.net/2012/10/14/powershell-and-wpf-writing-data-to-a-ui-from-a-different-runspace/

Update ComboBox Once item is selected

I'm lost and could really use some help. I'm trying to update a combo box with a list of column names from a csv file (selected by the open file button, and string input into textbox).
Function GetFileName($initialDirectory)
{
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null
$OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
$OpenFileDialog.initialDirectory = $initialDirectory
$OpenFileDialog.filter = "CSV (*.csv)| *.csv"
$OpenFileDialog.multiselect = $false
$OpenFileDialog.ShowDialog() | Out-Null
return $OpenFileDialog.FileName
}
Function GetColumnsFromFile
{
Param ($fileWithPath)
[string]$csvFileColumnTitles = Get-Content $fileWithPath -totalcount 1
[String[]]$csvFileColumnTitles = ($csvFileColumnTitles -replace ",", "|").Trim()
[String[]]$csvFileColumnTitles = ($csvFileColumnTitles -replace "`"", "").Trim()
[String[]]$listOfColumnTitles = $csvFileColumnTitles.Split('|',[System.StringSplitOptions]::RemoveEmptyEntries)
return $listOfColumnTitles
}
Function GUIBox
{
# Creates GUI Box In Memory
[reflection.assembly]::loadwithpartialname("System.Windows.Forms") | Out-Null
[reflection.assembly]::loadwithpartialname("System.Drawing") | Out-Null
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.drawing
$Form = New-Object system.Windows.Forms.Form
$Form.Width = '1200'
$Form.Height = '800'
# TabControl
$TabControl = New-Object System.Windows.Forms.TabControl
$TabControl.Name = "TabControl"
$TabControl.TabIndex = 4
$TabControl.SelectedIndex = 0
$TabControl.DataBindings.DefaultDataSourceUpdateMode = 0
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 0
$System_Drawing_Point.Y = 50
$TabControl.Location = $System_Drawing_Point
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 685
$System_Drawing_Size.Width = 1184
$TabControl.Size = $System_Drawing_Size
$Form.Controls.Add($TabControl)
# Test 1 Tab
$Test1_Tab = New-Object System.Windows.Forms.TabPage
$Test1_Tab.DataBindings.DefaultDataSourceUpdateMode = 0
$Test1_Tab.Name = "Test 1"
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 0
$System_Drawing_Point.Y = 50
$Test1_Tab.Location = $System_Drawing_Point
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 685
$System_Drawing_Size.Width = 1184
$Test1_Tab.Size = $System_Drawing_Size
$Test1_Tab.TabIndex = 1
$Test1_Tab.Text = "Test 1"
$Test1_Tab.UseVisualStyleBackColor = $True
$TabControl.Controls.Add($Test1_Tab)
# Open File Label
$SelectSourceFile_Label = New-Object System.Windows.Forms.Label
$SelectSourceFile_Label.Location = "10, 30"
$SelectSourceFile_Label.Name = "label"
$SelectSourceFile_Label.Size = "120, 20"
$SelectSourceFile_Label.TabIndex = 3
$SelectSourceFile_Label.Text = "Select Source File"
$Test1_Tab.Controls.Add($SelectSourceFile_Label)
# Open File Textbox
$SelectSourceFile_Textbox = New-Object System.Windows.Forms.TextBox
$SelectSourceFile_Textbox.Location = '10, 50'
$SelectSourceFile_Textbox.Size = '200, 20'
$SelectSourceFile_Textbox.TabIndex = 3
$SelectSourceFile_Textbox.Text = $Test1_FileInput_Textbox_String
$Test1_Tab.Controls.Add($SelectSourceFile_Textbox)
# Open File Button
$SelectSourceFile_Button = New-Object System.Windows.Forms.Button
$SelectSourceFile_Button.DialogResult = 'None'
$SelectSourceFile_Button.Location = '210, 50'
$SelectSourceFile_Button.Name = 'Open File Button'
$SelectSourceFile_Button.Size = '75, 25'
$SelectSourceFile_Button.TabIndex = 3
$SelectSourceFile_Button.Text = 'Open File'
$SelectSourceFile_Button.UseVisualStyleBackColor = $true
$SelectSourceFile_Button_Click = {$SelectSourceFile_Textbox.Text = GetFileName}
$SelectSourceFile_Button.add_Click($SelectSourceFile_Button_Click)
$Test1_Tab.Controls.Add($SelectSourceFile_Button)
# Select Open File Columns Label
$SelectSourceFileColumn_Label = New-Object System.Windows.Forms.Label
$SelectSourceFileColumn_Label.Location = "10, 90"
$SelectSourceFileColumn_Label.Name = "label"
$SelectSourceFileColumn_Label.Size = "150, 20"
$SelectSourceFileColumn_Label.TabIndex = 3
$SelectSourceFileColumn_Label.Text = "Select Source File Column"
$Test1_Tab.Controls.Add($SelectSourceFileColumn_Label)
# Select Open File Columns Dropdown
[String[]]$ColumnList = GetColumnsFromFile 'C:\Scripts\Tests\1Project\Test.csv'
Write-Host '$ColumnList =' $ColumnList
$SelectSourceFileColumn_Dropdown = New-Object 'System.Windows.Forms.ComboBox'
$SelectSourceFileColumn_Dropdown.FormattingEnabled = $True
$SelectSourceFileColumn_Dropdown.Location = '10, 110'
$SelectSourceFileColumn_Dropdown.Name = 'File Column'
$SelectSourceFileColumn_Dropdown.Size = '200, 20'
$SelectSourceFileColumn_Dropdown.TabIndex = 3
$SelectSourceFileColumn_Dropdown.Height = 30
$Test1_Tab.Controls.Add($SelectSourceFileColumn_Dropdown)
## Display GUI Box ##
$Form.ShowDialog()
}
GUIBox
The csv file...
"ColumnOne","ColumnTwo","ColumnThree"
"ColumnOneValueOne","ColumnTwoValueOne","ColumnThreeValueOne"
"ColumnOneValueTwo","ColumnTwoValueTwo","ColumnThreeValueTwo"
"ColumnOneValueThree","ColumnTwoValueThree","ColumnThreeValueThree"
So in the powershell window, we can see it is able to print the 3 column names. I know if I try this line [String[]]$ColumnList = GetColumnsFromFile $SelectSourceFile_Textbox.Text (replacing line 110), it will error out (because it will iterate through this line, before the user has a chance to input the selected file). So how would I update the combobox (with column names from the csv file) after the user has input their csv file?
One way you could do this is to use the button click to show the FolderBrowserDialog and if you get a filename from it, get the headings and add each one to the combobox.
You can use the same technique to populate the ComboBox when the user types into the textbox by creating a TextChanged event.
I got this to work using the following code:
function GUIBox {
#----------------------------------------------
#region Import the Assemblies
#----------------------------------------------
[void][reflection.assembly]::Load('System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089')
[void][reflection.assembly]::Load('System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089')
[void][reflection.assembly]::Load('System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')
[void][reflection.assembly]::Load('System.DirectoryServices, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')
[void][reflection.assembly]::Load('System.ServiceProcess, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')
#endregion Import Assemblies
#----------------------------------------------
#region Generated Form Objects
#----------------------------------------------
[System.Windows.Forms.Application]::EnableVisualStyles()
$form1 = New-Object 'System.Windows.Forms.Form'
$textbox1 = New-Object 'System.Windows.Forms.TextBox'
$combobox1 = New-Object 'System.Windows.Forms.ComboBox'
$buttonLoadCsv = New-Object 'System.Windows.Forms.Button'
$InitialFormWindowState = New-Object 'System.Windows.Forms.FormWindowState'
#endregion Generated Form Objects
#----------------------------------------------
# User Generated Script
#----------------------------------------------
function Get-FileName($initialDirectory)
{
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null
$OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
$OpenFileDialog.initialDirectory = $initialDirectory
$OpenFileDialog.filter = "CSV (*.csv)| *.csv"
$OpenFileDialog.multiselect = $false
$OpenFileDialog.ShowDialog() | Out-Null
return $OpenFileDialog.FileName
}
$form1_Load={
#TODO: Initialize Form Controls here
}
$buttonLoadCsv_Click={
#TODO: Place custom script here
$file = Get-FileName -initialDirectory $env:USERPROFILE
if ($file)
{
$textbox1.Text = $file
try
{
$headers = Import-Csv -Path $file | Get-Member | Where-Object -FilterScript {$_.MemberType -eq 'NoteProperty'} | Select-Object -ExpandProperty Name -Unique
Write-Host ($headers | Out-String)
$combobox1.Items.Clear()
foreach($header in $headers)
{
$combobox1.Items.Add($header)
}
}
catch
{
Write-Warning -Message "The following error occured while trying to get the headings for csv file $file`: $($_.Exception.Message)"
}
}
}
# --End User Generated Script--
#----------------------------------------------
#region Generated Events
#----------------------------------------------
$Form_StateCorrection_Load=
{
#Correct the initial state of the form to prevent the .Net maximized form issue
$form1.WindowState = $InitialFormWindowState
}
$Form_Cleanup_FormClosed=
{
#Remove all event handlers from the controls
try
{
$buttonLoadCsv.remove_Click($buttonLoadCsv_Click)
$form1.remove_Load($form1_Load)
$form1.remove_Load($Form_StateCorrection_Load)
$form1.remove_FormClosed($Form_Cleanup_FormClosed)
}
catch [Exception]
{ }
}
#endregion Generated Events
#----------------------------------------------
#region Generated Form Code
#----------------------------------------------
$form1.SuspendLayout()
#
# form1
#
$form1.Controls.Add($textbox1)
$form1.Controls.Add($combobox1)
$form1.Controls.Add($buttonLoadCsv)
$form1.ClientSize = '390, 76'
$form1.Name = 'form1'
$form1.Text = 'Form'
$form1.add_Load($form1_Load)
#
# textbox1
#
$textbox1.Location = '12, 14'
$textbox1.Name = 'textbox1'
$textbox1.Size = '284, 20'
$textbox1.TabIndex = 2
#
# combobox1
#
$combobox1.DropDownStyle = 'DropDownList'
$combobox1.FormattingEnabled = $True
$combobox1.Location = '12, 40'
$combobox1.Name = 'combobox1'
$combobox1.Size = '284, 21'
$combobox1.TabIndex = 1
#
# buttonLoadCsv
#
$buttonLoadCsv.Location = '302, 12'
$buttonLoadCsv.Name = 'buttonLoadCsv'
$buttonLoadCsv.Size = '75, 49'
$buttonLoadCsv.TabIndex = 0
$buttonLoadCsv.Text = 'Load Csv'
$buttonLoadCsv.UseVisualStyleBackColor = $True
$buttonLoadCsv.add_Click($buttonLoadCsv_Click)
$form1.ResumeLayout()
#endregion Generated Form Code
#----------------------------------------------
#Save the initial state of the form
$InitialFormWindowState = $form1.WindowState
#Init the OnLoad event to correct the initial state of the form
$form1.add_Load($Form_StateCorrection_Load)
#Clean up the control events
$form1.add_FormClosed($Form_Cleanup_FormClosed)
#Show the Form
return $form1.ShowDialog()
} #End Function
#Call the form
GUIBox | Out-Null

Powershell - DataViewGrid - Column Autosize

I am a complete novice when it comes to .NET and powershell and was wondering if you guys could assist. I am generating a Data Grid from a .CSV on a form and would like the grid to auto size columns accordingly. Also if I could lock the columns/rows from user adjustment that would be amazing.
Clear-Host
Function Populate-CycleCountDataGrid {
$InventoryListArray = New-Object System.Collections.ArrayList
$Script:InventoryList = #(Import-CSV C:\File.csv | Write-Output)
$InventoryListArray.AddRange($Script:InventoryList)
$CycleCountDataGrid.DataSource = $InventoryListArray
}
Function GenerateForm {
$objForm = New-Object System.Windows.Forms.Form
$InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState
$RefreshButton_Click = {
Populate-CycleCountDataGrid
}
# Form Setup
#*******************************************************************************************\
$OnLoadForm_StateCorrection= { $objForm.WindowState = $InitialFormWindowState }
$objForm.Text = "CycleCount"
$objForm.Name = "CycleCount"
$objForm.Size = New-Object System.Drawing.Size(600,480)
$objForm.StartPosition = 0
$objForm.AutoSize = $False
$objForm.MinimizeBox = $False
$objForm.MaximizeBox = $False
$objForm.WindowState = "Normal"
# DataGrid
#*******************************************************************************************\
$CycleCountDataGrid = New-Object System.Windows.Forms.DataGrid
$CycleCountDataGrid.Location = New-Object System.Drawing.Size(0,0)
$CycleCountDataGrid.Size = New-Object System.Drawing.Size(592,400)
$CycleCountDataGrid.AutoSize = $False
$CycleCountDataGrid.AllowSorting = $False
$CycleCountDataGrid.ReadOnly = $True
$CycleCountDataGrid.CaptionText = "Inventory List"
$CycleCountDataGrid.HeaderFont = New-Object System.Drawing.Font("Verdana",8.25,1,3,0)
$CycleCountDataGrid.HeaderForeColor = [System.Drawing.Color]::FromArgb(255,0,0,0)
$CycleCountDataGrid.Font = New-Object System.Drawing.Font("Verdana",8.25,[System.Drawing.FontStyle]::Bold)
$CycleCountDataGrid.BackColor = [System.Drawing.Color]::FromArgb(255,0,160,250)
$CycleCountDataGrid.AlternatingBackColor = [System.Drawing.Color]::FromArgb(255,133,194,255)
$CycleCountDataGrid.Name = "CycleCountDataGrid"
$CycleCountDataGrid.DataBindings.DefaultDataSourceUpdateMode = 0
$objForm.Controls.Add($CycleCountDataGrid)
#*******************************************************************************************/
# Refresh Button
#*******************************************************************************************\
$RefreshButton = New-Object System.Windows.Forms.Button
$RefreshButton.Location = New-Object System.Drawing.Size(0,400)
$RefreshButton.Size = New-Object System.Drawing.Size(590,45)
$RefreshButton.Name = "RefreshButton"
$RefreshButton.Text = "Refresh"
$RefreshButton.UseVisualStyleBackColor = $True
$RefreshButton.add_Click($RefreshButton_Click)
$RefreshButton.DataBindings.DefaultDataSourceUpdateMode = 0
$objForm.Controls.Add($RefreshButton)
#*******************************************************************************************/
$objForm.Topmost = $True
$objForm.Add_Shown({$objForm.Activate()})
$objForm.FormBorderStyle = 'Fixed3D'
$objForm.MaximizeBox = $False
$objForm.Add_FormClosing([System.Windows.Forms.FormClosingEventHandler]{
if ($objForm.DialogResult -eq "Cancel") {}
})
$InitialFormWindowState = $objForm.WindowState
$objForm.add_Load($OnLoadForm_StateCorrection)
$objForm.ShowDialog()
#*******************************************************************************************/
}
GenerateForm
Add the following code:
$CycleCountDataGrid.Columns | Foreach-Object{
$_.AutoSizeMode = [System.Windows.Forms.DataGridViewAutoSizeColumnMode]::AllCells
}
Change your control to a system.windows.forms.datagridview rather than just a datagrid. Then you have access to $CycleCountDataGrid.columns
Each column has a width property. The answer above will try to autosize each column but you could specify each one if you like.
$CycleCountDatarid.columns[0].width = 200
100 is the default
The secret to Autosizing a Windows.Forms.Datagrid is that it has a private method 'ColAutoResize' you can invoke with Reflection:
Function AutoResizeColumns([System.Windows.Forms.DataGrid] $dg1){
[System.Reflection.BindingFlags] $F = 'static','nonpublic','instance'
$ColAutoResizeMethod = $dg1.GetType().GetMethod('ColAutoResize', $F)
If($ColAutoResizeMethod) {
For ([int]$i = $dg1.FirstVisibleColumn; $i -lt $dg1.VisibleColumnCount; $i++){
$ColAutoResizeMethod.Invoke($dg1, $i) | Out-Null
}
}
}
Once you have that function, you can add it to the DataGrid's VisibleChanged and DataSourceChanged events so drawing and refreshing the DataGrid will invoke AutoResizeColumns:
$objForm.Controls["CycleCountDataGrid"].add_DatasourceChanged({ AutoResizeColumns $objForm.Controls["CycleCountDataGrid"] } )
$objForm.Controls["CycleCountDataGrid"].add_VisibleChanged({ AutoResizeColumns $objForm.Controls["CycleCountDataGrid"] } )
$objForm.ShowDialog() | Out-Null
There's probably a cleaner way to do this, but it's working for me.