Invoking a scriptblock when clicking a radio button - sql-server

I want my GUI to be able to dynamically produce an event based on the user clicking either Radio Button 1 or Radio Button 2.
I have seen some good tutorials on this but its called during a click on a button. I want to call it OnClick of the radio button.
Here is the code I have so far:
#Load Assemblies
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") | Out-Null
$net = New-Object -ComObject Wscript.Network
Add-Type -AssemblyName System.Windows.Forms
#Create the Form
#Draw form
function SQLDoTasks{
$Form = New-Object System.Windows.Forms.Form
$Form.width = 800
$Form.height = 600
$Form.BackColor = "lightblue"
$Form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::Fixed3D
$Form.Text = "Daily DBA Tasks"
$Form.maximumsize = New-Object System.Drawing.Size(525,350)
$Form.startposition = "centerscreen"
$Form.KeyPreview = $True
$Form.Add_KeyDown({if ($_.KeyCode -eq "Enter") {}})
$Form.Add_KeyDown({if ($_.KeyCode -eq "Escape")
{$Form.Close()}})
# Create a group that will contain your radio buttons
$MyGroupBox = New-Object System.Windows.Forms.GroupBox
$MyGroupBox.Location = '40,30'
$MyGroupBox.size = '400,150'
$MyGroupBox.text = "Specify the Sql environment?"
#Declare option buttons to allow user to select Dev or System Test
$RadioButton1 = New-Object System.Windows.Forms.RadioButton #create the radio button
$RadioButton1.Location = '20,40'
$RadioButton1.size = '350,20'
$RadioButton1.Checked = $false #is checked by default
$RadioButton1.Text = "Dev" #labeling the radio button
$RadioButton1.Checked($event)
#Declare option buttons to allow user to select Dev OR System Test
$RadioButton2 = New-Object System.Windows.Forms.RadioButton #create the radio button
$RadioButton2.Location = '20,70'
$RadioButton2.size = '350,20'
#$RadioButton2.Location = new-object System.Drawing.Point(10,40) #location of the radio button(px) in relation to the group box's edges (length, height)
#$RadioButton2.size = New-Object System.Drawing.Size(80,20) #the size in px of the radio button (length, height)
$RadioButton2.Checked = $false #is checked by default
$RadioButton2.Text = "System test" #labeling the radio button
$RadioButton2.Checked($event)
$event={
if ($RadioButton1.Checked){
[System.Windows.Forms.MessageBox]::Show("You select Dev")}
elseif ($RadioButton2.Checked){
[System.Windows.Forms.MessageBox]::Show("You Selected System Test")}
}
#Create List Box
$ListBox1 = New-Object System.Windows.Forms.ListBox
$ListBox1.Location = New-Object System.Drawing.Size(20,200)
$ListBox1.Size = New-Object System.Drawing.Size(260,20)
$ListBox1.Height = 80
#POPULATE WHAT IT WILL HOLD
$Servers = get-content -path "xxxx.csv"
write-host $Servers
ForEach ($Server in $Servers){
#$NL = "`r`n"
[void] $ListBox1.Items.Add($Server)
}
#Create the Form
# Add all the GroupBox controls on one line
$Form.Controls.Add($ListBox1)
$form.Controls.AddRange(#($MyGroupBox))
$MyGroupBox.Controls.AddRange(#($Radiobutton1,$RadioButton2))
$Form.Add_Shown({$Form.Activate()})
$dialogResult =$Form.ShowDialog()
}
SQLDoTasks

First, you have to declare the $event scriptblock before you add the event handler. So I would define both buttons, then the scriptblock and then add the handlers. Also, you probably should use the Add_Click callback:
#....
$RadioButton2 = New-Object System.Windows.Forms.RadioButton #create the radio button
$RadioButton2.Location = '20,70'
$RadioButton2.size = '350,20'
#$RadioButton2.Location = new-object System.Drawing.Point(10,40) #location of the radio button(px) in relation to the group box's edges (length, height)
#$RadioButton2.size = New-Object System.Drawing.Size(80,20) #the size in px of the radio button (length, height)
$RadioButton2.Checked = $false #is checked by default
$RadioButton2.Text = "System test" #labeling the radio button
$event={
if ($RadioButton1.Checked){
[System.Windows.Forms.MessageBox]::Show("You select Dev")}
elseif ($RadioButton2.Checked){
[System.Windows.Forms.MessageBox]::Show("You Selected System Test")}
}
$RadioButton1.Add_Click($event)
$RadioButton2.Add_Click($event)

Related

Powershell GUI not registering Radio Button as clicked [duplicate]

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

Powershell Forms - How to add context menu event handler to prevent open unless item selected?

I have a form with a listview for which I have a right click context menu. I'd like the menu to only appear if the right clikc is above the selected item in the listview - at the moment it appears anywhere in the listview windows and even if nothing is selected.
Add-Type -AssemblyName System.Windows.Forms
$form = New-Object System.Windows.Forms.Form
$form.Text = "Foo"
$form.Size = '400,400'
$CMitemEnable = New-Object System.Windows.Forms.ToolStripMenuItem
$CMitemEnable.Text = 'Enable'
$CMitemDisable = New-Object System.Windows.Forms.ToolStripMenuItem
$CMitemDisable.Text = 'Disable'
$lvcontextmenu = New-Object System.Windows.Forms.ContextMenuStrip
$lvcontextmenu.ShowImageMargin = $false
$lvcontextmenu.Items.AddRange(#($CMitemEnable,$CMitemDisable))
$listviewbox = New-Object System.Windows.Forms.ListView
$listviewbox.View = [System.Windows.Forms.View]::Details
$listviewbox.Location = '15,20'
$listviewbox.Size = '340,150'
$listviewbox.Columns.Add('Host',180) | Out-Null
$listviewbox.FullRowSelect = $true
$listviewbox.MultiSelect = $false
# $listviewbox.ContextMenuStrip = $lvcontextmenu
$InfoText = New-Object System.Windows.Forms.TextBox
$InfoText.Location = '15,180'
$InfoText.Size = '340,120'
$InfoText.Multiline = $true
$InfoText.ScrollBars = "Vertical"
$InfoText.ReadOnly = $true
$form.Controls.AddRange(#($listviewbox,$InfoText))
$listviewbox.Items.AddRange(#('Foobar1','foobar2'))
$listviewbox.Add_MouseDown({
$listviewbox.contextmenustrip = $null
If($listviewbox.SelectedItems.Count){
$listviewbox.contextmenustrip = $lvcontextmenu
$InfoText.AppendText("`r`n" + ($this.SelectedItems[0].Text))
}
Else {
$InfoText.AppendText("`r`nNothing selected")
$listviewbox.contextmenustrip = $null
}
})
# Show form
$form.ShowDialog() | Out-Null
$form.Dispose()
I've not done context menus before and can't see for the life of me how to implement the event handler for this - there's examples for C etc but can someone point me in the right direction for Powershell please?
Considering the following points:
Don't set ContextMenuStrip for the ListView
Handle MouseClick event, so first the item will be selected, then your code run. (As an alternative, if you prefer mouse down, then you need to need to put your logic in BeginInvoke to make sure it will run after selection of item.)
Using GetBound method of the selected item and e.Location, check if the clicked location is inside the item rectangle
Show the ContextMenuStrip using Show by passing Cursor.Position
Here is a working example:
Add-Type -AssemblyName System.Windows.Forms
$form = New-Object System.Windows.Forms.Form
$form.Text ="Test"
$form.Controls.AddRange(#(
($listView1 = [System.Windows.Forms.ListView] #{
Dock = [System.Windows.Forms.DockStyle]::Fill;
FullRowSelect = $true;
View = [System.Windows.Forms.View]::Details;
})
))
$contextMenuStrip1 = [System.Windows.Forms.ContextMenuStrip]#{}
$listView1.Columns.Add("C1") | Out-Null
$listView1.Columns.Add("C2") | Out-Null
$listView1.Items.Add("Item1") | Out-Null
$listView1.Items.Add("Item2") | Out-Null
$contextMenuStrip1.Items.Add("Menu 1") | Out-Null
$contextMenuStrip1.Items.Add("Menu 2") | Out-Null
$listView1.Add_MouseClick({param($sender,$e)
if ($e.Button -eq [System.Windows.Forms.MouseButtons]::Right){
if ($listView1.FocusedItem.GetBounds(
[System.Windows.Forms.ItemBoundsPortion]::Entire).Contains($e.Location)){
$contextMenuStrip1.Show([System.Windows.Forms.Cursor]::Position)
}
}
})
$form.ShowDialog() | Out-Null
$form.Dispose()
$contextMenuStrip1.Dispose()
Maybe there is a cleaner way, but this works for me:
First, remove line 22 ($listviewbox.ContextMenuStrip = $lvcontextmenu)
and then change the Click-handler for the $listviewbox into:
$listviewbox.Add_Click({
If($this.SelectedItems.Count){
$this.ContextMenuStrip = $lvcontextmenu
$InfoText.AppendText("`r`n" + ($this.SelectedItems[0].Text))
}
Else {
$this.ContextMenuStrip = $null
$InfoText.AppendText("`r`nNothing selected")
}
})
The following event handler works as intended - a combination of hints from both of you, thanks.
$listviewbox.Add_MouseUp({
$listviewbox.contextmenustrip = $null
If($listviewbox.SelectedItems.Count){
$listviewbox.contextmenustrip = $lvcontextmenu
$InfoText.AppendText("`r`n" + ($this.SelectedItems[0].Text))
}
Else {
$InfoText.AppendText("`r`nNothing selected")
$listviewbox.contextmenustrip = $null
}
})

Make Entire Borderless Form Draggable from Certain Object

I have a borderless winform (WPF is not an option) that I am trying to make draggable from an object that is serving as a custom sidebar. I have searched around and found some things that allow me to drag the sidebar within the form, but I need to be able to move $Form with the sidebar. Any thoughts? It seems like I will need to use Add-Type with some C# here.
Ok, since we don't have the code to your form, here's a demo for you. It is just a not-pretty borderless form that uses a label to demonstrate the various events needed to drag the entire form around. (in your case this would be the sidebar)
Add-Type -AssemblyName System.Windows.Forms
# set up some globals for dragging
$global:dragging = $false
$global:mouseDragX = 0
$global:mouseDragY = 0
#Form
$form = New-Object System.Windows.Forms.Form
$form.FormBorderStyle = "None"
$form.Font = New-Object System.Drawing.Font("Microsoft Sans Serif", 9.0, [System.Drawing.FontStyle]::Regular, [System.Drawing.GraphicsUnit]::Point)
$form.MinimumSize = New-Object System.Drawing.Size(456, 547)
$form.AutoScaleDimensions = New-Object System.Drawing.SizeF(7.0, 15.0)
$form.AutoScaleMode = [System.Windows.Forms.AutoScaleMode]::Font
$form.ClientSize = New-Object System.Drawing.Size(440, 509)
$form.ShowIcon = $false
$form.StartPosition = "CenterScreen"
$form.TopMost = $true
#lblDrag (this is the object used for dragging the form)
$lblDrag = New-Object System.Windows.Forms.Label
$lblDrag.Name = "lblDrag"
$lblDrag.BackColor = [System.Drawing.Color]::LightYellow
$lblDrag.Location = New-Object System.Drawing.Point(172, 226)
$lblDrag.Size = New-Object System.Drawing.Size(117, 27)
$lblDrag.Anchor = "Top","Right"
$lblDrag.BorderStyle = "FixedSingle"
$lblDrag.Text = "Drag form.."
$lblDrag.TextAlign = [System.Drawing.ContentAlignment]::MiddleCenter
# set the 'dragging' flag and capture the current mouse position
$lblDrag.Add_MouseDown( { $global:dragging = $true
$global:mouseDragX = [System.Windows.Forms.Cursor]::Position.X - $form.Left
$global:mouseDragY = [System.Windows.Forms.Cursor]::Position.Y -$form.Top
})
# move the form while the mouse is depressed (i.e. $global:dragging -eq $true)
$lblDrag.Add_MouseMove( { if($global:dragging) {
$screen = [System.Windows.Forms.Screen]::PrimaryScreen.WorkingArea
$currentX = [System.Windows.Forms.Cursor]::Position.X
$currentY = [System.Windows.Forms.Cursor]::Position.Y
[int]$newX = [Math]::Min($currentX - $global:mouseDragX, $screen.Right - $form.Width)
[int]$newY = [Math]::Min($currentY - $global:mouseDragY, $screen.Bottom - $form.Height)
$form.Location = New-Object System.Drawing.Point($newX, $newY)
}})
# stop dragging the form
$lblDrag.Add_MouseUp( { $global:dragging = $false })
# add a button so you will be able to close the form
$btnClose = New-Object System.Windows.Forms.Button
$btnClose.Name = "btnClose"
$btnClose.Anchor = "Top","Right"
$btnClose.Location = New-Object System.Drawing.Point(172, 454)
$btnClose.Size = New-Object System.Drawing.Size(117, 27)
$btnClose.Text = "&Close"
$btnClose.UseVisualStyleBackColor = $true
$btnClose.UseMnemonic = $true
$btnClose.DialogResult = [System.Windows.Forms.DialogResult]::OK
# add controls to the form
$form.Controls.Add($btnClose)
$form.Controls.Add($lblDrag)
$form.AcceptButton = $btnClose
# show the form and play around with the dragging label
$form.ShowDialog()
# when done, dispose of the form
$form.Dispose()

powershell combobox items to variable

I am trying to create a powershell Script with a Gui that gives the user a drop list of available drives and then when the user selects the drive and clicks ok the script maps that drive as M:\
But I cant work out how to get the selected item in the combo box to be passed into the variable $MapDrive
#List of Drives To Map
$DriveList = #("0. DGL_Data","1. P1","2. DGLFSG3","3. p3 (TPC)","4. p4","6. p6","7. p7","8. p8","9. p9","10. p10","11. p11","12. p12")
#Displays With Drive to Map
$MapDrive = convert.ToString($Dropdown.SelectedItem)
Function MapDrive {
If ($MapDrive -eq $DriveList[0]){
Write-Output Sucess > "C:\Users\andy.burton\Desktop\Practice Selector\Success.txt"}
ElseIf ($MapDrive -eq $DriveList[1]){
Write-Output BooYah > "C:\Users\andy.burton\Desktop\Practice Selector\Yes.txt"
}
Else {
Write-Output Failure > "C:\Users\andy.burton\Desktop\Practice Selector\Failed.txt"}
}
#test Function
Function test {
Write-Output $MapDrive > "C:\Users\andy.burton\Desktop\Practice Selector\Success.txt"
}
#Function to Create Form
Function GenerateForm {
#Define Drive Selector Main Form
Add-Type -AssemblyName System.Windows.Forms
$DGL = New-Object system.Windows.Forms.Form
$DGL.Text = "DGL Practice Manager"
$DGL.TopMost = $true
$DGL.BackgroundImage = [system.drawing.image]::FromFile("C:\Users\andy.burton\Desktop\Practice Selector\Images\medical.jpg")
$DGL.Icon = New-Object system.drawing.icon("C:\Users\andy.burton\Desktop\Practice Selector\Images\medical2.ico")
$DGL.Width = 600
$DGL.Height = 265
$DGL.MinimizeBox = $False
$DGL.MaximizeBox = $False
#Label to Display Instuctions
$label2 = New-Object system.windows.Forms.Label
$label2.Text = "Select which drive"
$label2.BackColor = "#e4f3fa"
$label2.AutoSize = $true
$label2.Width = 25
$label2.Height = 10
$label2.location = new-object system.drawing.point(20,28)
$label2.Font = "Microsoft Sans Serif,10"
$DGL.controls.Add($label2)
#Dropdown Box For Selecting Practice
$Dropdown = New-Object system.windows.Forms.ComboBox
$Dropdown.BackColor = "#e4f3fa"
$DropDown.DropDownStyle = [System.Windows.Forms.ComboBoxStyle]::DropDownList
$Dropdown.Width = 243
$Dropdown.Height = 20
$Dropdown.location = new-object system.drawing.point(21,73)
$Dropdown.Font = "Microsoft Sans Serif,10"
$DropDown.items.addrange($DriveList)
$DGL.controls.Add($Dropdown)
#Cancel Button to Cancel drive Selection
$Cancelbutton = New-Object system.windows.Forms.Button
$Cancelbutton.Text = "Cancel"
$Cancelbutton.Width = 60
$Cancelbutton.Height = 30
$Cancelbutton.location = new-object system.drawing.point(210,120)
$Cancelbutton.Font = "Microsoft Sans Serif,10"
$DGL.CancelButton = $Cancelbutton
$CancelButton.Add_Click({ $DGL.close();[System.Windows.Forms.Application]::Exit($null)})
$DGL.controls.Add($Cancelbutton)
#OK Button to Select Drive
$OKbutton = New-Object system.windows.Forms.Button
$OKbutton.Text = "OK"
$OKbutton.Width = 60
$OKbutton.Height = 30
$OKbutton.location = new-object system.drawing.point(140,120)
$OKbutton.Font = "Microsoft Sans Serif,10"
$DGL.AcceptButton = $OKbutton
$MapDrive = convert.ToString($Dropdown.SelectedItem)
#On click call PracticeSelectedCallBack to launch the application
$OKbutton.Add_Click({test ; $DGL.close()})
$DGL.controls.Add($OKbutton)
#Display the Form
$DGL.Add_Shown({$DGL.Activate()})
$DGL.ShowDialog()
}
GenerateForm
I also want to hide the powershell window but not the gui I have tried -window hidden but that hid everything
The ComboBox has several events that you can tie into that will do various things. One of the events is a SelectedIndexChanged. You can add that event to your ComboBox object and update $MapDrive
This code $MapDrive = convert.ToString($Dropdown.SelectedItem) will only fire once during the initial compile. You have to use events to trigger code changes after compile during runtime.
Also, in Powershell you can use the following command [System.Windows.Forms.ComboBox] | gm to get a list of the methods, and properties of the object. You can use [System.Windows.Forms.checkedlistbox].GetEvents() to get a list of events of an object.

PowerShell DataGridView ComboBoxColumn Default Value

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

Resources