0

Good day!

Creating a form on PowerShell - System.Windows.Forms.Form.

In the process, several questions arose.

  1. The form contains ComboBox and ListBox blocks. ComboBox contains a list of organizations in advance. When selecting an organization from the drop-down list, all departments of the selected organization should be substituted in the ListBox.

How can this be organized?

  1. How to add scrolling for the ListBox, not just to see the slider, but what would actually scroll the list in the ListBox?

Code below:

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

<#----======= Departments&Section =======----#>
$Organizations = @("OOO 'COMPANY-1'","OOO 'COMPANY-2'","OOO 'COMPANY-3'","OOO 'COMPANY-4'")
$DepartmentsCOMPANY1 = @("Department 1","Department 2","Department 3","Department 4")
$DepartmentsCOMPANY2 = @("Department 5","Department 6","Department 7")

<#----======= Departments&Section =======----#>
<#----======= Basic form =======----#>

$main_form = New-Object System.Windows.Forms.Form
$main_form.Text ='Создание пользовательской учетной записи в домене'
$main_form.Width = 100
$main_form.Height = 100
$main_form.AutoSize = $true

<#----======= Basic form =======----#> 
<#----======= Signature FIO =======----#>

$LabelFIO = New-Object System.Windows.Forms.Label
$LabelFIO.Text = "ФИО (полностью)"
$LabelFIO.Font = New-Object System.Drawing.Font("Comic Sans MS",8,[System.Drawing.FontStyle]::Regular)
$LabelFIO.Location  = New-Object System.Drawing.Point(2,10)
$LabelFIO.AutoSize = $true
$main_form.Controls.Add($LabelFIO)

<#----======= Signature FIO =======----#>
<#----======= TextBox FIO =======----#>

$TextBoxFIO = New-Object System.Windows.Forms.TextBox
$TextBoxFIO.Location  = New-Object System.Drawing.Point(2,30)
$TextBoxFIO.Text = ""
$TextBoxFIO.Size = New-Object System.Drawing.Size(155,20)
$main_form.Controls.Add($TextBoxFIO)

<#----======= TextBox FIO =======----#>
<#----======= Signature Name =======----#>

$LabelName = New-Object System.Windows.Forms.Label
$LabelName.Text = "Имя"
$LabelName.Font = New-Object System.Drawing.Font("Comic Sans MS",8,[System.Drawing.FontStyle]::Regular)
$LabelName.Location  = New-Object System.Drawing.Point(2,55)
$LabelName.AutoSize = $true
$main_form.Controls.Add($LabelName)

<#----======= Signature Name =======----#>
<#----======= TextBox Name =======----#>

$TextBoxName = New-Object System.Windows.Forms.TextBox
$TextBoxName.Location  = New-Object System.Drawing.Point(2,75)
$TextBoxName.Text = ""
$TextBoxName.Size = New-Object System.Drawing.Size(155,20)
$main_form.Controls.Add($TextBoxName)

<#----======= TextBox Name =======----#>
<#----======= Signature Surname =======----#>

$LabelSurname = New-Object System.Windows.Forms.Label
$LabelSurname.Text = "Фамилия"
$LabelSurname.Font = New-Object System.Drawing.Font("Comic Sans MS",8,[System.Drawing.FontStyle]::Regular)
$LabelSurname.Location  = New-Object System.Drawing.Point(2,100)
$LabelSurname.AutoSize = $true
$main_form.Controls.Add($LabelSurname)

<#----======= Signature Surname =======----#>
<#----======= TextBox Surname =======----#>

$TextBoxSurname = New-Object System.Windows.Forms.TextBox
$TextBoxSurname.Location  = New-Object System.Drawing.Point(2,120)
$TextBoxSurname.Text = ""
$TextBoxSurname.Size = New-Object System.Drawing.Size(155,20)
$main_form.Controls.Add($TextBoxSurname)

<#----======= TextBox Surname =======----#>
<#----======= Signature Organization =======----#>

$LabelName = New-Object System.Windows.Forms.Label
$LabelName.Text = "Организация"
$LabelName.Font = New-Object System.Drawing.Font("Comic Sans MS",8,[System.Drawing.FontStyle]::Regular)
$LabelName.Location  = New-Object System.Drawing.Point(180,10)
$LabelName.AutoSize = $true
$main_form.Controls.Add($LabelName)

<#----======= Signature Organization =======----#>
<#----======= ComboBox Organization =======----#>

$ComboBoxOrganization = New-Object System.Windows.Forms.ComboBox
Foreach ($Organization in $Organizations)
{
    [void]$ComboBoxOrganization.Items.Add($Organization) 
}
$ComboBoxOrganization.Refresh();
$ComboBoxOrganization.Location  = New-Object System.Drawing.Point(180,30)
$main_form.Controls.Add($ComboBoxOrganization)

<#----======= ComboBox Organization =======----#>
<#----======= ListBox Departments =======----#>

$listBox = New-Object System.Windows.Forms.ListBox
$listBox.Location = '180,75'
$listBox.Text = $DepartmentsSALAIR
$listBox.AutoSize = $true
$listBox.ScrollAlwaysVisible = $false

if ($ComboBoxOrganization.SelectedItem -eq $Organizations[0])
{
    $i = 5
    foreach ($DepartmentCOMPANY1 in $DepartmentsCOMPANY1)
    {
        $CheckBox = New-Object System.Windows.Forms.CheckBox
        $CheckBox.Location = New-Object System.Drawing.Point(2,$i)
        $CheckBox.Text = $DepartmentCOMPANY1
        $CheckBox.AutoSize = $true
        $listBox.Controls.Add($LabelDepsSalair)
        $i = $i+17
    }
}
$main_form.Controls.Add($ListBox)

<#----======= ListBox Departments =======----#>

$main_form.ShowDialog()
  • I would create a Hashtable where the Keys are the organizations and the Values are arrays of departments for those organizations. Then fill your combobox looping over the $hash.Keys and as soon as the user makes a selection, fill the Listbox using `$listBox.Items.Clear(); foreach ($dept in $hash['TheSelectedItem']) {$listBox.Items.Add($dept)}`. Remove `$listBox.ScrollAlwaysVisible = $false` – Theo Mar 01 '23 at 13:15
  • Can you show me exmaple, how i can create this Hashtable for my code? – Catcher Rem Mar 01 '23 at 13:31

1 Answers1

0

As requested, here's how you should be able to combine the organizations with their departments in a Hashtable and use that info to fill and use the combobox and listbox in your form:

First create the Hashtable where the organizations and departments are combined.

$hash = @{
    'COMPANY-1' = 'Department 1','Department 2','Department 3','Department 4'
    'COMPANY-2' = 'Department 5','Department 6','Department 7'
}

Next in your form, create and pre-fill the Combobox

$ComboBoxOrganization          = New-Object System.Windows.Forms.ComboBox
$ComboBoxOrganization.Location = New-Object System.Drawing.Point(180,30)
$ComboBoxOrganization.Sorted   = $true
foreach ($Organization in $hash.Keys) {
    [void]$ComboBoxOrganization.Items.Add($Organization) 
}
$ComboBoxOrganization.SelectedIndex = 0    # set to top item

# add an event handler for when the selected index has been changed
$ComboBoxOrganization.Add_SelectedIndexChanged({
    $listbox.BeginUpdate()
    # remove the current content from the listbox
    $listBox.Items.Clear()
    # now fill it again with the departments that belong to the selected organization
    # you can refer to the Combobox here with automatic variable $this
    foreach ($dept in $hash[$this.SelectedItem]) {  
        [void]$listBox.Items.Add($dept)
    }
    $listbox.EndUpdate()
})
$main_form.Controls.Add($ComboBoxOrganization)

Then create and prefill the Listbox

$listBox          = New-Object System.Windows.Forms.ListBox
$listBox.Location = New-Object System.Drawing.Point(180,75)
$listBox.AutoSize = $true
$listbox.Sorted   = $true
# if you want a scrollbar to appear automatically you do NOT set
# $listBox.ScrollAlwaysVisible = $false

foreach ($dept in $hash[$ComboBoxOrganization.SelectedItem]) {  
    [void]$listBox.Items.Add($dept)
}
$main_form.Controls.Add($listBox)
Theo
  • 57,719
  • 8
  • 24
  • 41
  • But i don't understand what is automatic variable "$this"? Where it is announced and how it works? – Catcher Rem Mar 02 '23 at 06:09
  • @CatcherRem The [$this](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_automatic_variables?view=powershell-7.2#this) automatic variable can be used in a scriptblock like an event handler. There it is a reference to the originating object itself, so if the event is trigered from your `$ComboBoxOrganization` object, inside its scriptblock for short you can use `$this` – Theo Mar 02 '23 at 13:01
  • Theo, can ypu help me with problem described below? – Catcher Rem Mar 03 '23 at 14:53
  • Theo, can you look this link: https://stackoverflow.com/questions/75647650/powershell-windowsforms-change-listbox-via-selecteditemchanged-in-combobox – Catcher Rem Mar 06 '23 at 06:27
  • @CatcherRem Just posted an answer there ;) – Theo Mar 06 '23 at 14:09