I'm having some trouble making my charts appear in 3D, here's my code
[Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms.DataVisualization")
$WeekTable = #{
"Week1" = 50
"Week2" = 50
}
$WeekChart = New-Object System.Windows.Forms.DataVisualization.Charting.Chart
$WeekChart.Width = 1200
$WeekChart.Height = 768
$WeekChartArea = New-Object System.Windows.Forms.DataVisualization.Charting.ChartArea3DStyle
$WeekChartArea.Enable3D = $true
$WeekChart.ChartAreas.Add($WeekChartArea)
$WeekChart.Series.Add("Data")
$WeekChart.Series["Data"].Points.DataBindXY($WeekTable.Keys, $WeekTable.Values)
#$WeekChart.Series["Data"].ChartType = [System.Windows.Forms.DataVisualization.Charting.SeriesChartType]::Pie
# Display chart on form
$WeekChart.Anchor = [System.Windows.Forms.AnchorStyles]::Bottom -bor [System.Windows.Forms.AnchorStyles]::Right -bor
[System.Windows.Forms.AnchorStyles]::Top -bor [System.Windows.Forms.AnchorStyles]::Left
$Form = New-Object Windows.Forms.Form
$Form.Text = "Escape Windows XP statistics"
$Form.Width = 1024
$Form.Height = 820
$Form.controls.add($WeekChart)
$Form.Add_Shown({$Form.Activate()})
$Form.ShowDialog()
The chart shows up fine on my form but it is not displayed in 3D. The Enable3D property is true as it should be?? if i check when the script has finished
The problem you're seeing is that the ChartArea3DStyle is not a ChartArea, because it does not inherit from the ChartArea class. However, you are using it like it is a ChartArea when you call $WeekChart.ChartAreas.Add($WeekChartArea). I don't know why that isn't throwing an exception, but it sure seems to me like it should.
Instead, you need to simply create a ChartArea, then change its Area3DStyle property to the value of your ChartArea3DStyle instance. Don't treat the ChartArea3DStyle object like a ChartArea, because it isn't one.
$Area3DStyle = New-Object System.Windows.Forms.DataVisualization.Charting.ChartArea3DStyle;
$Area3DStyle.Enable3D = $true;
$ChartArea = $WeekChart.ChartAreas.Add('ChartArea');
$ChartArea.Area3DStyle = $WeekChartArea;
The final script would look like this:
[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms.DataVisualization")
$WeekTable = #{
"Week1" = 50
"Week2" = 50
}
$WeekChart = New-Object System.Windows.Forms.DataVisualization.Charting.Chart
$WeekChart.Width = 1200
$WeekChart.Height = 768
$Area3DStyle = New-Object System.Windows.Forms.DataVisualization.Charting.ChartArea3DStyle;
$Area3DStyle.Enable3D = $true;
$ChartArea = $WeekChart.ChartAreas.Add('ChartArea');
$ChartArea.Area3DStyle = $Area3DStyle;
$ChartSeries = $WeekChart.Series.Add("Data")
$WeekChart.Series["Data"].Points.DataBindXY($WeekTable.Keys, $WeekTable.Values)
#$WeekChart.Series["Data"].ChartType = [System.Windows.Forms.DataVisualization.Charting.SeriesChartType]::Pie
# Display chart on form
$WeekChart.Anchor = [System.Windows.Forms.AnchorStyles]::Bottom -bor [System.Windows.Forms.AnchorStyles]::Right -bor
[System.Windows.Forms.AnchorStyles]::Top -bor [System.Windows.Forms.AnchorStyles]::Left
$Form = New-Object Windows.Forms.Form
$Form.Text = "Escape Windows XP statistics"
$Form.Width = 1024
$Form.Height = 820
$Form.controls.add($WeekChart)
$Form.Add_Shown({$Form.Activate()})
$Form.ShowDialog()
Related
I am trying to output the result of the ping command to a textbox (windows forms GUI) using workflow/parallel and the message appears
"This type of assignment is not supported. Only variable names (i.e.: $variable) may be used as the target of an assignment statement."
picture
How can this issue be resolved?
Add-Type -assembly System.Windows.Forms
workflow parallelPing {
parallel {
$text1_box.Text = ping "google.com"
$text2_box.Text = ping "8.8.8.8"
$text3_box.Text = ping "stackoverflow.com"
}
}
$gui1 = New-Object System.Windows.Forms.Form
$gui1.Width = 1000
$gui1.Height = 700
$gui1.AutoSize = $false
$text1_box = New-Object System.Windows.Forms.TextBox
$text1_box.Location = New-Object System.Drawing.Point(10,20)
$text1_box.Multiline = $true
$text1_box.Width = 540
$text1_box.Height = 100
$gui1.Controls.Add($text1_box)
$text2_box = New-Object System.Windows.Forms.TextBox
$text2_box.Location = New-Object System.Drawing.Point(10,130)
$text2_box.Multiline = $true
$text2_box.Width = 540
$text2_box.Height = 100
$gui1.Controls.Add($text2_box)
$text3_box = New-Object System.Windows.Forms.TextBox
$text3_box.Location = New-Object System.Drawing.Point(10,240)
$text3_box.Multiline = $true
$text3_box.Width = 540
$text3_box.Height = 100
$gui1.Controls.Add($text3_box)
$getPing = New-Object System.Windows.Forms.Button
$getPing.Location = New-Object System.Drawing.Point(560,110)
$getPing.Width = 170
$getPing.Height = 90
$getPing.Text = '&Ping'
$getPing.Add_Click({parallelPing})
$gui1.Controls.Add($getPing)
$gui1.ShowDialog()
Since you are trying to assign the variable in the parallel block, use $workflow to access the workflow scope.
$workflow:Text1_box.text =
See this link for more details.
This works
$getPing = New-Object System.Windows.Forms.Button
$getPing.Location = New-Object System.Drawing.Point(560,110)
$getPing.Width = 170
$getPing.Height = 90
$getPing.Text = '&Ping'
$getPing.Add_Click({pingInfo})
$gui1.Controls.Add($getPing)
workflow parallelPing {
parallel {
$workflow:a1 = ping "google.com"
$workflow:a2 = ping "8.8.8.8"
$workflow:a3 = ping "stackoverflow.com"
}
$pingResult = #($a1, $a2, $a3)
return $pingResult
}
function pingInfo{
$text1_box.Lines = (parallelPing)[0]
$text2_box.Lines = (parallelPing)[1]
$text3_box.Lines = (parallelPing)[2]
}
$gui1.ShowDialog()
Thanks!
I'm trying to make a form in PowerShell that gets locked to a fixed position on the desktop.
Because whenever I press the "Show Desktop" button on the bottom right corner on Win 8.1, the form disappears until I open a different window and close it.
I just want it there like it's a widget, here's a part of the code i'm using:
Add-Type -AssemblyName System.Windows.Forms
Add-Type -Assembly System.Drawing
$Image = [System.Drawing.Image]::Fromfile("Panel.png")
$Form = New-Object system.Windows.Forms.Form
$Form.BackgroundImage = $Image
$Form.BackgroundImageLayout = "None"
$Form.Text = "Reboot Server"
$Form.Width = 517
$Form.Height = 134
$Form.ControlBox = $False
$Form.StartPosition = 'Manual'
$Form.Location = "1390, 300"
$Form.FormBorderStyle = 'None'
$Form.BackColor = "#000000"
$Form.MaximizeBox = $False
$Form.MinimizeBox = $False
$Form.Icon = "icon.ico"
$Form.Image = [System.Drawing.Image]::Fromfile("Panel.png")
$Form.ShowInTaskbar = $False
$Font = New-Object System.Drawing.Font("Tahoma",10, [System.Drawing.FontStyle]::Bold)
$Form.Font = $Font
$Label = New-Object System.Windows.Forms.Label
$Label.Text = ""
$Label.AutoSize = $True
$Form.Controls.Add($Label)
' Button 1 - Reboot Server'
$Button1 = new-object System.Windows.Forms.Button
$Button1.Location = new-object System.Drawing.Size(234,51)
$Button1.Size = new-object System.Drawing.Size(77,55)
$Button1.AutoSize = $True
$Button1.Add_Click({start-process "Reboot.lnk"})
$Button1.FlatStyle = [System.Windows.Forms.FlatStyle]::Flat
$Button1.FlatAppearance.BorderSize=0
$Button1.BackColor = "Transparent"
$Button1.ForeColor = "Transparent"
$Button1.FlatAppearance.MouseDownBackColor = "Transparent"
$Button1.FlatAppearance.MouseOverBackColor = "Transparent"
$Button1.FlatAppearance.BorderColor = "#252525"
$Form.Controls.Add($Button1)
'----------------------------------------
$Form.ShowDialog() | Out-Null
Exit 0
For gadget style positions try to use a little snippet that I have made:
$Poistion = 'RightBottom'
$Coordinates = switch ($Poistion)
{
'LeftTop' { 0, 0 }
'LeftBottom' { 0, $([System.Windows.Forms.Screen]::PrimaryScreen.WorkingArea.Bottom - $Form.Height) }
'RightTop' { $([System.Windows.Forms.Screen]::PrimaryScreen.WorkingArea.Width - $Form.Width), 0 }
'RightBottom' { $([System.Windows.Forms.Screen]::PrimaryScreen.WorkingArea.Width - $Form.Width), $([System.Windows.Forms.Screen]::PrimaryScreen.WorkingArea.Bottom - $Form.Height) }
}
$Form.Location = New-Object System.Drawing.Point($Coordinates)
To keep your form up at the time when you activate "Show Desktop" set TopMost property to $True and MinimizeBox property to $False. Like so:
$Form.TopMost = $True
$Form.MinimizeBox = $False
When you click on Show Desktop or use its hotkey (Win+D) windows tries to send Minimize All command to running applications. After minimizing all the windows that can be minimized, it then takes the desktop and "raises" it to the top of the window stack so that no other windows cover it.
You could also try to use sizing events. Like so:
$Form_Resize={
$Form.WindowState = 'Normal'
}
$Form.add_Resize($Form_Resize)
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()
I'm working on a PowerShell script that uses forms and panels that are docked. I was able to create the form and panels just fine, but I'm having issues getting a listbox to resize during runtime using $inputbox.Bottom = $form.Height - 215 to control the size, but I recieve the error
'Bottom' is a read-only property.
Simply using Fill in the panel will not work because I have buttons above and below the listbox. Here is a sample of my code:
[void] [System.Reflection.Assembly]::LoadWithPartialName(“System.Windows.Forms”)
[void] [System.Reflection.Assembly]::LoadWithPartialName(“System.Drawing”)
$form.ResizeEnd
$form = New-Object System.Windows.Forms.Form
$form.Size = New-Object System.Drawing.Size(1040,459)
$form.KeyPreview = $true
$form.StartPosition = ‘centerscreen’
$form.BackColor = 'MidnightBlue'
$form.Add_KeyDown({if($_.KeyCode -eq "Escape"){$form.Close()}})
$form.Text = "Dialog Box 2.0"
$form.Icon = [system.drawing.icon]::ExtractAssociatedIcon($PSHOME + "\powershell_ise.exe")
$buttonPanel3 = New-Object Windows.Forms.Panel
$buttonPanel3.Size = New-Object Drawing.Size #(290,70)
$buttonPanel3.Dock = "left"
$buttonPanel3.BackColor = 'Blue'
$inputbox = New-Object System.Windows.Forms.ListBox
$inputbox.BorderStyle = 'NONE'
$inputbox.Font = New-Object System.Drawing.Font(“segoe UI”,9)
$inputbox.SelectionMode = "MultiExtended"
$inputbox.Left = 10
$inputbox.Top = 105
$inputbox.Width = 200
$inputbox.Bottom = $form.Height -215
$inputbox.Height = $form.Height -215
$buttonPanel3.Controls.Add($inputbox)
$form.Controls.Add($buttonPanel3)
$form.ShowDialog()
If someone could give some sample code of a listbox that resizes (mainly concerned with vertical expansion) when you resize the form that would be excellent.
I ended up completely rearranging my form and using the fill method, but I wanted to put in a tidbit about form resizing since that was the true issue here.
The resize handler for the form would be $form.Add_Resize({}). Inside the brackets I could modify the height and width properties as desired. In this case, I only wanted the height property, so the code would be like:
[void] [System.Reflection.Assembly]::LoadWithPartialName(“System.Windows.Forms”)
[void] [System.Reflection.Assembly]::LoadWithPartialName(“System.Drawing”)
$form.ResizeEnd
$form = New-Object System.Windows.Forms.Form
$form.Size = New-Object System.Drawing.Size(1040,459)
$form.KeyPreview = $true
$form.StartPosition = ‘centerscreen’
$form.BackColor = 'MidnightBlue'
$form.Add_KeyDown({if($_.KeyCode -eq "Escape"){$form.Close()}})
$form.Text = "Dialog Box 2.0"
$form.Icon = [system.drawing.icon]::ExtractAssociatedIcon($PSHOME + "\powershell_ise.exe")
$form.Add_Resize({
$inputbox.Height = $form.Height -215
})
$buttonPanel3 = New-Object Windows.Forms.Panel
$buttonPanel3.Size = New-Object Drawing.Size #(290,70)
$buttonPanel3.Dock = "left"
$buttonPanel3.BackColor = 'Blue'
$inputbox = New-Object System.Windows.Forms.ListBox
$inputbox.BorderStyle = 'NONE'
$inputbox.Font = New-Object System.Drawing.Font(“segoe UI”,9)
$inputbox.SelectionMode = "MultiExtended"
$inputbox.Left = 10
$inputbox.Top = 105
$inputbox.Width = 200
$inputbox.Height = $form.Height -215
$buttonPanel3.Controls.Add($inputbox)
$form.Controls.Add($buttonPanel3)
$form.ShowDialog()
I am trying to show a DateTimePicker in a WinForms form in PowerShell. When the form appears, the date can be changed, but hitting the dropdown button doesn't show the calendar. It seems like something is happening, it's just not visible.
What stupid thing am I missing here?
$form = New-Object Windows.Forms.Form
$form.Size = New-Object Drawing.Size #(400, 400)
$form.StartPosition = "CenterScreen"
$form.Text = "When do you want the snapshot to be taken?"
$form.Font = New-Object Drawing.Font("Microsoft Sans Serif",12)
$form.FormBorderStyle = [Windows.Forms.FormBorderStyle]::Fixed3D
$panel = New-Object Windows.Forms.FlowLayoutPanel
$panel.Height = 400
$panel.Width = 400
$panel.AutoScroll = $true
$panel.FlowDirection = [Windows.Forms.FlowDirection]::TopDown
$panel.WrapContents = $false
$titleText = New-Object Windows.Forms.Label
$titleText.AutoSize = $true
$titleText.Text = "When do you want the snapshot to be taken?"
$panel.Controls.Add($titleText)
$datePicker = New-Object Windows.Forms.DateTimePicker
$datePicker.ShowUpDown = $false
$datePicker.MinDate = $now
$datePicker.MaxDate = $now.AddMonths(3); #arbitrary
$datePicker.MaxSelectionCount = 1
$datePicker.Width = 350
$datePicker.Enabled = $false
$panel.Controls.Add($datePicker)
$form.Controls.Add($panel)
$drc = $form.ShowDialog()
Your code seems to work fine on my computer. I copy-pasted your code and added Add-Type to top:
Add-Type -AssemblyName System.Windows.Forms
And changed the $datePicker.Enabled:
$datePicker.Enabled = $true
When run, I can change the date/time and also the dropdown is working as expected: