I'm trying to check an item into a ListBox after clicking a Radio Button, but no success.
Specifically, I'm trying to check a Active Directory Group already listed.
I made this piece of script:
$Action = foreach ($SecurityGroup in $ADSecurityGroup)
{
$SecurityGroup.Name -eq "AD Example"
{
[void] $ADGroups.Items.Add($SecurityGroup.Name, $True)
}
}
And after added to Add_Click of Raddio Button:
$RadioButton.Add_Click($Action)
Someone could help me?
Here is an example I provide to another OP, though it's using a list box, and a comboxbox, the premise for doing this via a button in the same.
Populate ComboBox2 depending on ComboBox1 selection
Another example of Comboxbox to a list
(You could just change the combobox to whatever form element you choose) :
Add-Type -AssemblyName System.Drawing
$ComboBox = New-Object System.Windows.Forms.ComboBox
$ComboBox.Location = New-Object System.Drawing.Point(10,10)
$ComboBox.Items.AddRange(#("One","Two"))
$RichTextBox = New-Object System.Windows.Forms.RichTextBox
$RichTextBox.Location = New-Object System.Drawing.Point(10,40)
$Form = New-Object System.Windows.Forms.Form
$Form.Controls.Add($ComboBox)
$Form.Controls.Add($RichTextBox)
$ComboBox.Add_TextChanged({
# Code here
switch($ComboBox.Text){
"One" {$RichTextBox.Text = "This is one"}
"Two" {$RichTextBox.Text = "This is two"}
}
})
$Form.ShowDialog()
As for this...
Specifically, I'm trying to check an Active Directory Group already
listed.
... you just do validation before your add another item.
I achieved what I was looking for with this:
$RadioButton.Add_Click({
for ($i = 0; $i -lt $ADGroups.Items.Count; $i++)
{
If ($ADGroups.Items[$i] -match 'AD Group that I wanted to change status')
{
$ADGroups.SetItemChecked($i, $true)
}
}
})
I publish it in case it is useful to someone.
Thanks a lot!
Related
I'm certain I'm missing something stupid, but I can't get this figured. I have a script that creates a "Please Wait" popup while the code is running. The issue is that I can't get the popup to close after the script is done.
Here is how the popup gets called:
Function CheckShuffle()
{
#Check Selection
If ($Global:x -eq "" -or $Global:x -eq '0')
{
if ( $null -eq ('System.Windows.MessageBox' -as [type]) )
{
Add-Type -AssemblyName PresentationFramework
}
[System.Windows.MessageBox]::Show('You must select your part first', 'Warning', 'OK')
}
Else
{
OpenSplash
#Shuffle
CloseSplash
}
}
Here is the code for the popup:
Function OpenSplash()
{
$Splash = New-Object system.Windows.Forms.Form
$Splash.StartPosition = 'CenterScreen'
$Splash.Size = New-Object System.Drawing.Size(350,200)
$SplashLabel = New-Object System.Windows.Forms.Label
$Splash.Controls.Add($SplashLabel)
$SplashLabel.Location = New-Object System.Drawing.Point(100,60)
$SplashLabel.Font = [System.Drawing.Font]::new("Microsoft Sans Serif", 16, [System.Drawing.FontStyle]::Bold)
$SplashLabel.Text = "Please Wait"
$SplashLabel.AutoSize = $True
$Splash.Visible = $True
$Splash.Update()
}
I've tried a few ways to close it:
Function CloseSplash()
{
$This.Parent.Close()
}
This one one closes the primary form, not the splash screen.
Function CloseSplash()
{
$Splash.Close()
}
That one throws an error: "You cannot call a method on a null valued expression"
It looks like Powershell is forgetting what $Splash is, but I cannot figure out how to tell it.
Thank you all!
Edit: Worth noting, if I put the code all together instead of calling it, the popup closes as intended.
Jeroen answered the question in a comment, and I don't see how to mark that as the answer, so I'm reposting here!
The solution:
I needed to make $splash global. This was super easy, I just had to make it say:
$Global:Splash
Thanks again Jeroen!
I am attempting to create a form in Powershell. It contains a ComboBox dropdown option that I am using as a required field. Until an option is selected, the continue button will be disabled. This is the code for the ComboBox and the button enabling:
$TSTypeBox.Name = "TSType"
$TSTypeBox.Location = New-Object System.Drawing.Point(116,100)
$TSTypeBox.Size = New-Object System.Drawing.Size(145,20)
$TSTypeBox.add_MouseHover($ShowHelp)
$TSTypeBox.DropDownStyle = "DropDownList"
Foreach ($item in ("1","2","3","4","5")) {
$TSTypeBox.Items.Add($item) | Out-Null
}
$TSTypeBox.SelectedItem = $TSLocation
$handler_TSTypeBox_SelectedIndexChanged= {
If (($TSTypeBox.Text) -and ($ComputerNameBox.Text))
{
$OKButton.Enabled = 1
}
Else
{
$OKButton.Enabled = 0
}
}
$TSTypeBox.add_SelectedIndexChanged($handler_TSTypeBox_SelectedIndexChanged)
This code in particular works as intended so I'm not worried about that. I am here about the $TSTypeBox.SelectedItem = $TSLocation line that I included. I have code elsewhere that pulls the IP address of the computer the program is being run on, which is then matched against an if/elseif/else statement to determine if the computer belongs to 1 or to 2, which are options that you can see were added to the ComboBox in the code above.
That if/else statement updated the $TSLocation variable which I then use to force the selection of one of the dropdown options in the ComboBox. This works as well, but unfortunately it does not enable the continue button as I would like. I had a hard time looking up issues about this because its super particular and I am probably doing this incorrectly (I have very little experience with Powershell scripting). If you have any additional questions about this please let me know. Thanks!
Ok, this might illustrate your problem.
Just because you set the SelectedItem value to something, doesn't mean the SelectedIndex changes
#
Add-Type -AssemblyName System.Windows.Forms -ErrorAction Stop
#
$TSLocation = '2'
#
$form = New-Object System.Windows.Forms.Form
$form.Text = "Test"
$form.MinimumSize = '430,495'
$form.MaximumSize = '430,545'
$form.StartPosition = 'CenterScreen'
#
# Add form objects
#
$TSTypeBox = New-Object System.Windows.Forms.ComboBox
$TSTypeBox.Name = "TSType"
$TSTypeBox.Location = '116,100'
$TSTypeBox.Size = '145,20'
$TSTypeBox.add_MouseHover($ShowHelp)
$TSTypeBox.DropDownStyle = "DropDownList"
Foreach ($item in ("1","2","3","4","5")) {
$TSTypeBox.Items.Add($item) | Out-Null
}
$ComputerNameBox = New-Object System.Windows.Forms.TextBox
$ComputerNameBox.Location = '120,20'
$ComputerNameBox.Size = '120,17'
$ComputerNameBox.Text = 'test'
$OutputBox = New-Object System.Windows.Forms.TextBox
$OutputBox.Location = '120,240'
$OutputBox.Size = '120,17'
$OkButton = New-Object System.Windows.Forms.Button
$OkButton.Location = '120,200'
$OkButton.Size = '54,24'
$OkButton.Text = 'OK'
$form.controls.AddRange(#($TSTypeBox,$OkButton,$ComputerNameBox,$OutputBox))
#
# Main Script goes here
#
$handler_TSTypeBox_SelectedIndexChanged= {
$OutputBox.Text = "SelectedIndex is " + $TSTypeBox.SelectedIndex
If (($TSTypeBox.Text) -and ($ComputerNameBox.Text))
{
$OKButton.Enabled = 1
}
Else
{
$OKButton.Enabled = 0
}
}
$TSTypeBox.add_SelectedIndexChanged($handler_TSTypeBox_SelectedIndexChanged)
#
$TSTypeBox.SelectedIndex = $TSTypeBox.FindStringExact($TSLocation)
#
# Show form
$form.ShowDialog() | Out-Null
$form.Dispose()
# End
If in doubt, always best to simplify your script and add debug ,logging or output that shows what values are changing
Now that the problem is clear - this article points you in the right direction:
How do I set the selected item in a comboBox to match my string using C#?
In order to render more user-friendly my script I would like to load a dialog in which a complete folder tree (from the C:\ root) is browsable and where I could select multiple (sub)folders through check boxes. How can I accomplish such task?
P.S.: the best solution should also include hidden folders
Edit: after the evaluation of the comments and the early reply I will clarify what I am looking for. I would like to create a dialog in which the folder tree is showed, where I can expand or collapse the branches and where I can select parent folders and/or some of the children/leaves (subfolders and/or files) at the same time.
By using New-object System.Windows.Forms.OpenFileDialog and change
$FormOpenFileDialog.Multiselect = $False to True you have a File-browser that can select several folders.
$FormOpenFileDialog = New-object System.Windows.Forms.OpenFileDialog
$FormOpenFileDialog.initialDirectory = ""
$FormOpenFileDialog.Title = ""
$FormOpenFileDialog.Filter = ""
$FormOpenFileDialog.Multiselect = $True
$FormOpenFileDialog.showHelp = $true
$FormOpenFileDialog.ShowDialog()
$ApplicationForm.Controls.Add($FormOpenFileDialog)
By Adding this to a Form, binded to a button maby is the best solution ?
$ApplicationForm = New-Object System.Windows.Forms.Form
$BtnOpenFileDialog = New-object System.Windows.Forms.Button
$BtnOpenFileDialog.text= "Open Folder"
$BtnOpenFileDialog.location = "50,50"
$BtnOpenFileDialog.size = "80,20"
$BtnOpenFileDialog.Add_Click({ GenerateFormOpenFileDialog })
$ApplicationForm.Controls.Add($BtnOpenFileDialog)
function GenerateFormOpenFileDialog { # Start GenerateFormOpenFileDialog
$FormOpenFileDialog = New-object System.Windows.Forms.OpenFileDialog
$FormOpenFileDialog.InitialDirectory = ""
$FormOpenFileDialog.Title = ""
$FormOpenFileDialog.Filter = ""
$FormOpenFileDialog.Multiselect = $True
$FormOpenFileDialog.ShowHelp = $true
$FormOpenFileDialog.ShowDialog()
} # End GenerateFormOpenFileDialog
# Initlize the form
$ApplicationForm.Add_Shown({$ApplicationForm.Activate()})
[void] $ApplicationForm.ShowDialog()
Why Filebrowser and not folderbrowserdialog ?
folderbrowserdialog has more limitations.
FileBrowser
FolderBrowser
If you want to create a form, Sapians has a great forum for this.
https://www.sapien.com/
https://www.sapien.com/forums/
I created an array of Check boxes. I could create a event handler for each check box separately but as it would be lengthy code I thought if I could create them using loop. When event handler is written inside loop the event is being handled but the result shown is wrong i.e -> when I select i'th check box the event is handled but $checkBox_Charts[$i].Checked is always returning False whether the box is checked or unchecked.
Edit 1:
I realized even when checked event is raised on any check box this code is returning checked status of last element in for loop,
Adding the complete code
Code:
function whichCharts(){
Write-Host "CP1: in whichCharts"
foreach ($key_chart in $charts.Keys){
Write-Host $charts[$key_chart]
}
}
function checkbox_test{
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
# Set the size of your form
$Form = New-Object System.Windows.Forms.Form
$Form.width = 1000
$Form.height = 600
$Form.Text = ”My First Form with a working checkbox”
# Set the font of the text to be used within the form
$Font = New-Object System.Drawing.Font("Times New Roman",12)
$Form.Font = $Font
$charts = #("x","y","z")
$checkBox_Charts =[System.Windows.Forms.checkbox[]]::new(3)
$index_checkBox_Charts=0
for ($i=0;$i -lt $charts.Count; $i++){
$CheckBox = new-object System.Windows.Forms.checkbox
$height = (60*$i)+20
$CheckBox.Location = new-object System.Drawing.Size(100,$height)
$CheckBox.Size = '150,50'
$CheckBox.Text = $charts[$i]
$CheckBox.Checked = $false
$checkBox_Charts[$i] = $CheckBox
}
# Add an OK button
$OKButton = new-object System.Windows.Forms.Button
$OKButton.Location = '50,500'
$OKButton.Size = '100,40'
$OKButton.Text = "OK"
$OKButton.DialogResult=[System.Windows.Forms.DialogResult]::OK
#Add a cancel button
$CancelButton = new-object System.Windows.Forms.Button
$CancelButton.Location = '255,100'
$CancelButton.Size = '100,40'
$CancelButton.Text = "Cancel"
$CancelButton.DialogResult=[System.Windows.Forms.DialogResult]::Cancel
# Create a group that will contain your radio buttons
$MyGroupBox = New-Object System.Windows.Forms.GroupBox
$MyGroupBox.Location = '40,30'
$MyGroupBox.size = '800,400'
$MyGroupBox.text = "Do you like Cheese?"
# Add all the GroupBox controls on one line
$MyGroupBox.Controls.AddRange(#($checkBox_Charts))
$Form.Controls.AddRange(#($MyGroupBox,$OKButton,$CancelButton))
########### This is the important piece ##############
# #
# Do something when the state of the checkbox changes #
#######################################################
for($i=0; $i -lt 2; $i++){
$checkBox_Charts[$i].Add_CheckStateChanged({
Write-Host "CP2: in Add_CheckStateChanged " + $checkBox_Charts[$i].Checked
Write-Host $checkBox_Charts[$i]
Write-Host $i})
}
# Activate the form
$Form.Add_Shown({$Form.Activate()})
[void] $Form.ShowDialog()
}
#Call the function
checkbox_test
Inside the scriptblock for the CheckStateChanged event, the variable $i is unknown. To make its value available there, you must have stored it in a property the checkbox can read. The best place for this is the checkbox's own Tag property.
In your code, create the checkboxes like this:
$charts = "x","y","z" # no need to surround this with #()
$checkBox_Charts = [System.Windows.Forms.checkbox[]]::new($charts.Count)
for ($i = 0; $i -lt $charts.Count; $i++){
$CheckBox = new-object System.Windows.Forms.checkbox
$height = (60*$i)+20
$CheckBox.Location = new-object System.Drawing.Size(100,$height)
$CheckBox.Size = '150,50'
$CheckBox.Text = $charts[$i]
$CheckBox.Checked = $false
# save the index $i in the Tag property of the checkbox itself
$CheckBox.Tag = $i
$CheckBox.Add_CheckStateChanged({
# inside this scriptblock, the variable $i is unknown
# so we use the index value stored in the Tag property earlier
Write-Host "CP2: in Add_CheckStateChanged $($this.Checked)"
Write-Host "CheckBox index: $($this.Tag)"
Write-Host $checkBox_Charts[$this.Tag]
Write-Host
})
$checkBox_Charts[$i] = $CheckBox
}
Then remove the code you have here:
########### This is the important piece ##############
# #
# Do something when the state of the checkbox changes #
#######################################################
for($i=0; $i -lt 2; $i++){
$checkBox_Charts[$i].Add_CheckStateChanged({
Write-Host "CP2: in Add_CheckStateChanged " + $checkBox_Charts[$i].Checked
Write-Host $checkBox_Charts[$i]
Write-Host $i})
}
because this is now all done while creating the checkboxes earlier (and won't work as you have noticed)
As sidenotes:
change this obsolete/deprecated code:
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
into
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
straighten the curly quotes you have in $Form.Text = ”My First Form with a working checkbox” to become $Form.Text = "My First Form with a working checkbox".
They won't hurt you in this case, but using curly quotes in code can lead to numerous weird problems. Never use them in code.
Inside a control's event handler, the $this automatic variable refers to the control itself
I hope there i can get an answer for this quick. Im populating a list box based on radio button being selected. I want the list box to highlight the row automatically so that when i click the button the relevant action can happen based on the selection. In this case it will be a sql server instance. See extract of code for adding it to ListBox1.
ForEach ($Server in $Servers)
{
#$NL = "`r`n"
[void] $ListBox1.Items.Add($Server)
#$ListBox1.Items.selectedItem
}
Example:
$form = New-Object System.Windows.Forms.Form
$listbox = New-Object System.Windows.Forms.ListBox
$listbox.SelectionMode = "MultiSimple"
$listbox.Items.Add("item1") | Out-Null
$listbox.Items.Add("item2") | Out-Null
$listbox.Items.Add("item3") | Out-Null
$listbox.Items.Add("item4") | Out-Null
for($i = 0; $i -lt $listbox.Items.Count; $i++) {
$listbox.SetSelected($i, $true)
}
$form.Controls.Add($listbox)
$form.ShowDialog()