Search code examples
powershellscrollcomboboxlistboxwindows-forms-core

PowerShell.WindowsForms.Change ListBox via Selecting item in ComboBox


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()

Solution

  • 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)