No PowerShell Form datagrid selected - powershell

I have created a script that must select all the items in a powershell form, based on a variable. If the variable $bolCheckAllNumberedItems has the value '$False, then the grid should not be selected, in case the variable $bolCheckAllNumberedItems has the value '$True', the whole grid should be selected.
The code I have:
Clear-Host
$bolCheckAllNumberedItems = $True
$frmTest = New-Object 'System.Windows.Forms.Form'
$btnOk = New-Object 'System.Windows.Forms.Button'
$chkAllItems = New-Object 'System.Windows.Forms.CheckBox'
$DataGridForTest = New-Object 'System.Windows.Forms.DataGridView'
$InitialFormWindowState = New-Object 'System.Windows.Forms.FormWindowState'
$frmTest.Controls.Add($btnOk)
$frmTest.Controls.Add($chkAllItems)
$frmTest.Controls.Add($DataGridForTest)
$frmTest.AutoScaleDimensions = New-Object System.Drawing.SizeF(6, 13)
$frmTest.AutoScaleMode = 'Font'
$frmTest.ClientSize = New-Object System.Drawing.Size(284, 261)
$frmTest.Name = 'frmTest'
$frmTest.StartPosition = 'CenterScreen'
$frmTest.Text = 'Test'
#
# btnOk
#
$btnOk.Location = New-Object System.Drawing.Point(186, 220)
$btnOk.Name = 'btnOk'
$btnOk.Size = New-Object System.Drawing.Size(75, 23)
$btnOk.TabIndex = 1
$btnOk.Text = '&Ok'
$btnOk.UseVisualStyleBackColor = $True
$btnOk.add_Click($btnOk_Click)
#
# chkAllItems
#
$chkAllItems.Location = New-Object System.Drawing.Point(22, 22)
$chkAllItems.Name = 'chkAllItems'
$chkAllItems.Size = New-Object System.Drawing.Size(104, 24)
$chkAllItems.TabIndex = 1
$chkAllItems.Text = 'Select all items'
$chkAllItems.UseVisualStyleBackColor = $True
$chkAllItems.add_CheckedChanged($chkAllItems_CheckedChanged)
#
# DataGridForTest
#
$DataGridForTest.ColumnHeadersHeightSizeMode = 'AutoSize'
$DataGridForTest.Location = New-Object System.Drawing.Point(22, 52)
$DataGridForTest.Name = 'DataGridForTest'
$DataGridForTest.Size = New-Object System.Drawing.Size(240, 150)
$DataGridForTest.TabIndex = 0
$DataGridForTest.TabStop = $False
$DataGridForTest.ColumnCount = 1
$DataGridForTest.ColumnHeadersVisible = $true
$DataGridForTest.Columns[0].Name = "Number"
$DataGridForTest.Columns[0].width = 100
$DataGridForTest.ScrollBars = 'Vertical'
$DataGridForTest.ReadOnly = $True
$DataGridForTest.AllowUserToAddRows = $False
$DataGridForTest.AllowUserToDeleteRows = $False
$DataGridForTest.AllowUserToResizeColumns = $False
$DataGridForTest.AllowUserToResizeRows = $False
$DataGridForTest.SelectionMode = "FullRowSelect"
$DataGridForTest.MultiSelect = $true
#----------------------------------------------
$ArrayNumbers = #("one","two","three","for","five","six","seven","eight","nine","ten")
[system.collections.arraylist]$ArrayWithHeader = #()
ForEach ($object in $ArrayNumbers)
{
$value = [pscustomobject]#{'Number' = $object}
$ArrayWithHeader.Add($value) | Out-Null
$value = $null
}
$ArrayWithHeader | foreach {$DataGridForTest.Rows.Add($_."Number") | Out-Null }
if($bolCheckAllNumberedItems)
{
$chkAllItems.Checked = $true
$DataGridForTest.SelectAll()
}
$chkAllItems.Add_Click({
if($chkAllItems.Checked)
{
$DataGridForTest.SelectAll()
}
else
{
$DataGridForTest.ClearSelection()
}
})
$btnOk.add_Click({$frmTest.Close()})
[void]$frmTest.ShowDialog()
What is wrong with my code? Help is appreciated and with kind regards,
The Sting Pilot

I think the easiest way of doing this is to start your script with a small function you can call inside the checkbox Click() event aswell as in an added form event called Add_Shown()
function Select-Grid ([bool]$selectAll) {
$chkAllItems.Checked = $selectAll
if ($selectAll) {
$DataGridForTest.SelectAll()
}
else {
$DataGridForTest.ClearSelection()
}
}
This way you can remove these lines:
if($bolCheckAllNumberedItems)
{
$chkAllItems.Checked = $true
$DataGridForTest.SelectAll()
}
and instead write
# call the helper function with the Checked value of the $chkAllItems checkbox
$chkAllItems.Add_Click({ Select-Grid $chkAllItems.Checked })
# this is an added event that fires when the form is first shown
$frmTest.Add_Shown( { Select-Grid $bolCheckAllNumberedItems } )
[void]$frmTest.ShowDialog()
# very important! dispose of the form when you are finished with it
$frmTest.Dispose()
An alternative approach is to again remove these lines:
if($bolCheckAllNumberedItems)
{
$chkAllItems.Checked = $true
$DataGridForTest.SelectAll()
}
and change the event $chkAllItems.Add_Click() to use a different event:
$chkAllItems.Add_CheckedChanged({
if($chkAllItems.Checked) {
$DataGridForTest.SelectAll()
}
else {
$DataGridForTest.ClearSelection()
}
})
Activate that event when the form is first shown and finish the code:
$frmTest.Add_Shown( { $chkAllItems.Checked = $bolCheckAllNumberedItems } )
[void]$frmTest.ShowDialog()
# and not forget to get rid of the form from memory
$frmTest.Dispose()
Using the CheckedChanged() method does not need an extra helper function as with the first approach.

Related

Powershell Form GUI with draggable objects

I want to create a PowerShell based GUI with windows forms to display items in different containers and enable the user to drag items (control objects) from one container to another. Because of some bad flickering I copied the answer from this question and converted the code into PowerShell:
How to double buffer .NET controls on a form?
The problem is, that the objects are "smearing" on the form when I start dragging them and I can't find how to solve this.
class Dictionary : System.Collections.DictionaryBase
{
Dictionary() {}
[Bool]Exists([System.Object] $Key) {return ($Key -in $this.Keys) }
}
function SetDoubleBuffered()
{
param([System.Windows.Forms.Control] $TargetControl)
[System.Reflection.PropertyInfo] $DoubleBufferedProp = [System.Windows.Forms.Control].GetProperty("DoubleBuffered", [System.Reflection.BindingFlags]::NonPublic -bor [System.Reflection.BindingFlags]::Instance)
$DoubleBufferedProp.SetValue($TargetControl, $True, $Null)
}
function Button_MouseDown()
{
[CmdletBinding()]
param(
[parameter(Mandatory=$True)][System.Object] $Sender,
[parameter(Mandatory=$True)][System.EventArgs] $EventArguments
)
$Sender.Tag.DragStart = $False
$Sender.Tag.StartX = $EventArguments.X
$Sender.Tag.StartY = $EventArguments.Y
}
function Button_MouseUp()
{
[CmdletBinding()]
param(
[parameter(Mandatory=$True)][System.Object] $Sender,
[parameter(Mandatory=$True)][System.EventArgs] $EventArguments
)
$Sender.Tag.DragStart = $False
$Sender.Tag.StartX = 0
$Sender.Tag.StartY = 0
}
function Button_MouseMove()
{
[CmdletBinding()]
param(
[parameter(Mandatory=$True)][System.Object] $Sender,
[parameter(Mandatory=$True)][System.EventArgs] $EventArguments
)
if ($EventArguments.Button.value__ -gt 0)
{
if (-not $Sender.Tag.DragStart)
{
if ([System.Math]::sqrt([System.Math]::Pow($Sender.Tag.StartX - $EventArguments.X, 2) + [System.Math]::Pow($Sender.Tag.StartY - $EventArguments.Y, 2)) -ge 10)
{
$Sender.Tag.DragStart = $true
}
}
else
{
$Sender.Left = $Sender.Left + ($EventArguments.X - $Sender.Tag.StartX)
$Sender.Top = $Sender.Top + ($EventArguments.Y - $Sender.Tag.StartY)
}
}
else
{
$Sender.Tag.DragStart = $False
$Sender.Tag.StartX = 0
$Sender.Tag.StartY = 0
}
}
function OpenForm()
{
$Form = [System.Windows.Forms.Form]::new()
$Form.Text = "DragTest"
$Form.Width = 900
$Form.Height = 900
$Button = [System.Windows.Forms.Button]::new()
$Button.Left = 10
$Button.Top = 30
$Button.Height = 20
$Button.Width = 100
$Button.Text = "MyButton"
$Button.Name = "SomeButton"
$Button.Tag = [Dictionary]::new()
$Button.Add_MouseDown({Button_MouseDown -Sender $Button -EventArguments $_})
$Button.Add_MouseUp({Button_MouseUp -Sender $Button -EventArguments $_})
$Button.Add_MouseMove({Button_MouseMove -Sender $Button -EventArguments $_})
$Form.Controls.Add($Button)
SetDoubleBuffered -TargetControl $Form
SetDoubleBuffered -TargetControl $Button
$Form.ShowDialog() | Out-Null
}
cls
OpenForm

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

Powershell textBox using watermark

I created some code here to do watermark but it's not working. I need to know the function and ways of how to control watermark. I'm trying to create a form with watermark.
We are only beginners in terms of powershell.
$TextBox1 = New-Object system.Windows.Forms.TextBox
$TextBox1.multiline = $false
$TextBox1.Name = "TextBox1"
$TextBox1.width = 100
$TextBox1.height = 20
$TextBox1.location = New-Object System.Drawing.Point(141,170)
$TextBox1.Font = 'Microsoft Sans Serif,10'
$WatermarkText = 'Enter Username'
$TextBox1.ForeColor = 'LightGray'
$TextBox1.Text = $WatermarkText
$TextBox1_Enter={
if($TextBox1.Text -eq $WatermarkText)
{
#Clear the text
$TextBox1.Text = ""
$TextBox1.ForeColor = 'WindowText'
}
}
$TextBox1_Leave={
if($TextBox1.Text -eq "")
{
#Display the watermark
$TextBox1.Text = $WatermarkText
$TextBox1.ForeColor = 'LightGray'
}
}
$TextBox1_VisibleChanged={
if($TextBox1.Visible -and $TextBox1.Tag -eq $null)
{
#Initialize the watermark and save it in the Tag property
$TextBox1.Tag = $TextBox1.Text;
$TextBox1.ForeColor = 'LightGray'
#If we have focus then clear out the text
if($TextBox1.Focused)
{
$TextBox1.Text = ""
$TextBox1.ForeColor = 'WindowText'
}
}
}
The scriptblocks you have are just assigned to variables, not registered as event handlers on the $TextBox object.
Use something like $TextBox.Add_Enter( {#your code })
instead of $TextBox_Enter={#your code }

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.