Powershell textBox using watermark - powershell

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 }

Related

No PowerShell Form datagrid selected

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.

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 Update an already active form

So I'm trying to insert red dots into some kind of map, which I do with creating new pictureboxes after reading their coordinates out of an txt-file.
My goal now is to remove or create new boxes, while the form.ShowDialog() was already used.
I found a way of closing the whole form and running everything again, which kind of works but is very ugly in my opinion. Was wondering if there is another way of checking if new coordinates have been added to the txt-file or removed and if that is the case, creating or removing the corresponding boxes.
(I tried .Refresh but that seems to do nothing at all)
function MakeForm {
[void][reflection.assembly]::LoadWithPartialName("System.Windows.Forms")
[System.Windows.Forms.Application]::EnableVisualStyles();
$form = new-object Windows.Forms.Form
$form.Text = "Image Viewer"
$form.Width = 270;
$form.Height = 270;
$path = (Get-Item "Insert Path here")
$path2 = (Get-Item "Insert Path here")
$img = [System.Drawing.Image]::Fromfile($path);
$img2 = [System.Drawing.Image]::FromFile($path2);
$test = Get-Content -Path "Insert Path here"
$test
$pictureBoxes = New-Object 'System.Collections.Generic.List[Windows.Forms.PictureBox]'
$i=1
Foreach ($Line in $test){
if ($Line -like "*in 2*"){
$i++
$Split1= $Line.Split(" ")
$x=$Split1[5]
$y=$Split1[6]
$pictureBox = New-Object Windows.Forms.PictureBox
$pictureBox.Width = $img.Size.Width;
$pictureBox.Height = $img.Size.Height;
$pictureBox.Location = New-object System.Drawing.Size($x,$y)
$pictureBox.Image = $img;
$form.Controls.Add($pictureBox)
$pictureBoxes.Add($pictureBox)
Write-Host $pictureBoxes[$i]
$form.Add_Shown( { $form.Activate() } )
}
}
$pictureBox20 = New-Object Windows.Forms.PictureBox
$pictureBox20.Width = $img2.Size.Width;
$pictureBox20.Height = $img2.Size.Height;
$pictureBox20.Image = $img2;
$form.Controls.Add($pictureBox20)
$button1 = New-Object System.Windows.Forms.Button
$button1.Width=25
$button1.Height=223
$button1.Location = New-Object System.Drawing.Point(223,0)
$form.Controls.Add($button1)
$button1.Add_Click({
#Button for removing a box for testing purposes
$form.Controls.Remove($pictureBoxes[3])
})
$button2 = New-Object System.Windows.Forms.Button
$button2.Width=25
$button2.Height=223
$button2.Location = New-Object System.Drawing.Point(260,0)
$form.Controls.Add($button2)
$button2.Add_Click({
#This Button should refresh the whole form, if possible without doing everything again
$form.Close()
$form.Dispose()
MakeForm
})
$form.Add_Shown( { $form.Activate() } )
$form.ShowDialog()
}
MakeForm

How to get the sender to mouse-right-click menu in Powershell forms

I use Dynamic Labels.
I need to know on which dynamic label right click was pressed.
When I double click the server name it writes the label I pressed.
But how can I get the label I pressed in ContextMenuStrip?
This is the relevant part of my script:
$contextMenuStrip1 = New-Object System.Windows.Forms.ContextMenuStrip
$Menu1a = $contextMenuStrip1.Items.Add("Item 1")
$Menu1a.add_Click(
{
param($Sender,$EventArgs) write-host $Sender.name
Write-Host $this.Text
})
$Menu1b = $contextMenuStrip1.Items.Add("Item 2")
$Menu1b.add_Click({Write-Host $this.Text})
$Global:DynLblElemCol1 = foreach($Server in $Servers)
{
$Col = New-Object System.Windows.Forms.Label
$Col.Size = New-Object System.Drawing.Size(100, 18)
$col.TextAlign = "MiddleCenter"
$col.Text = $Server
$Col.Name = $Server
$Col.Add_DoubleClick({param($Sender,$EventArgs) write-host $Sender.Text})
$Col.ContextMenuStrip = $contextMenuStrip1
$Col
}
foreach($item in $DynLblElemCol1)
{
$item.Location = New-Object System.Drawing.Point(80, $CheckBoxCounter)
$Form1.Controls.Add($item)
$CheckBoxCounter = $item.Bottom + $LineSpace # increment our counter
}
}

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.