Alex_P
Alex_P

Reputation: 2952

ComboBox.SelectedItem is null

I populated a combobox with AD SamAccountName items. When selecting one of the items, one can push a button in order to retrieve information from that account. However, when clicking the button I receive the below error:

Cannot validate argument on parameter 'Identity'. The argument is null. Provide a valid value for the argument, and then try running the command again.

The command the error refers to is:

$Label_User_ItemContent.Text = (Get-ADUser -Identity $ComboBox.SelectedItem).SamAccountName

The crucial part of the code is:

        $ComboBox = New-Object -TypeName System.Windows.Forms.ComboBox
        $ComboBox.Width = 300
        $ComboBox.Location = New-Object -TypeName System.Drawing.Point(250, 25)

        $Users = Get-ADUser -Filter * | Where-Object {$_.SamAccountName -match '^adminA'}
        ForEach ($User in $Users){
            $ComboBox.Items.Add($User.SamAccountName)
        }
        $ComboBox.SelectedIndex = 1

            $MainWindow.Controls.Add($ComboBox)

        $Button_Check_TEST = New-Object -TypeName System.Windows.Forms.Button
        $Button_Check_TEST.Location = New-Object -TypeName System.Drawing.Size(350, 150)
        $Button_Check_TEST.Size = New-Object -TypeName System.Drawing.Size(150, 50)
        $Button_Check_TEST.Text = 'Check'

        $MainWindow.Controls.Add($Button_Check_TEST)

        $Button_Check_TEST.Add_Click({
            Try{
                $Label_User_ItemContent.Text = (Get-ADUser -Identity $ComboBox.SelectedItem).SamAccountName
            }
            Catch{
                Write-Verbose -Verbose $_.Exception.Message
            }
        })

The problem is, that I need two layers. Basically, there should be a menu with four different options, one of them is 'User'. When clicking on 'User' the ComboBox and the 'Click'-Button shall appear. Using the code above without the 'User'-Button works fine.

Question: Why does the ComboBox.SelectedItem not work when I use a button to 'create' the ComboBox?

The complete code is below:

    $font = New-Object -TypeName System.Drawing.Font("Times New Roman", 18, [System.Drawing.FontStyle]::Bold)

    $MainWindow = New-Object -TypeName System.Windows.Forms.Form
    $MainWindow.Text = 'PIM v10 Administrator Window'
    $MainWindow.Width = 600
    $MainWindow.Height = 555
    $MainWindow.AutoSize = $true

    $Button_User = New-Object -TypeName System.Windows.Forms.Button
    $Button_User.Location = New-Object -TypeName System.Drawing.Size(25, 25)
    $Button_User.Size = New-Object -TypeName System.Drawing.Size(200, 75)
    $Button_User.Text = 'User'
    $Button_User.Font = $font

        $MainWindow.Controls.Add($Button_User)

    $Button_User.Add_Click({
    $Label_User = New-Object -TypeName System.Windows.Forms.Label
    $Label_User.Text = 'Given Name:'
    $Label_User.Location = New-Object -TypeName System.Drawing.Point(250, 50)
    $Label_User.AutoSize = $true

        $MainWindow.Controls.Add($Label_User)

    $Label_User_ItemContent = New-Object -TypeName System.Windows.Forms.Label
    $Label_User_ItemContent.Text = ''
    $Label_User_ItemContent.Location = New-Object -TypeName System.Drawing.Point(250, 100)

        $MainWindow.Controls.Add($Label_User_ItemContent)

    $ComboBox = New-Object -TypeName System.Windows.Forms.ComboBox
    $ComboBox.Width = 300
    $ComboBox.Location = New-Object -TypeName System.Drawing.Point(250, 25)

    $Users = Get-ADUser -Filter * | Where-Object {$_.SamAccountName -match '^adminA'}
     ForEach ($User in $Users){
         $ComboBox.Items.Add($User.SamAccountName)
        }
     $ComboBox.SelectedIndex = 1

        $MainWindow.Controls.Add($ComboBox)

     $Button_Check_TEST = New-Object -TypeName System.Windows.Forms.Button
     $Button_Check_TEST.Location = New-Object -TypeName System.Drawing.Size(350, 150)
     $Button_Check_TEST.Size = New-Object -TypeName System.Drawing.Size(150, 50)
     $Button_Check_TEST.Text = 'Check'

     $MainWindow.Controls.Add($Button_Check_TEST)

     $Button_Check_TEST.Add_Click({
            Try{
                $Label_User_ItemContent.Text = (Get-ADUser -Identity $ComboBox.SelectedItem).SamAccountName
            }
            Catch{
                Write-Verbose -Verbose $_.Exception.Message
            }
        })

     if (-not ($ComboBox.SelectedItem -eq $null)){
         $Label_User_ItemContent.Text = (Get-ADUser -Identity $ComboBox.SelectedItem).SamAccountName
     }
     else {
        Write-Host -Object "Object is null"
     }
    })
    $MainWindow.ShowDialog()

Upvotes: 0

Views: 1143

Answers (1)

ArcSet
ArcSet

Reputation: 6860

So whats happening is you are creating variables in the wrong scope

$Button_User.Add_Click({
    $ComboBox = New-Object -TypeName System.Windows.Forms.ComboBox
    $Label_User_ItemContent = New-Object -TypeName System.Windows.Forms.Label
    $MainWindow.Controls.Add($ComboBox)
    $Label_User_ItemContent = New-Object -TypeName System.Windows.Forms.Label
    $Button_Check_TEST.Add_Click({
        $Label_User_ItemContent.Text = (Get-ADUser -Identity 
        $ComboBox.SelectedItem).SamAccountName
    )}
})

Since you are creating the Combo and the Lable inside a Add_click action. Those Values only exist when the action is taken and in the $MainWindows.Controls. The items are then cleared from memory

When you run the next action $Button_Check_TEST.Add_Click() since the variables are cleared then $ComboBox and $Label_User_ItemContent equal nothing.

A fix would be to place them outside the $Button_User.Add_Click() event

$ComboBox = New-Object -TypeName System.Windows.Forms.ComboBox
$Label_User_ItemContent = New-Object -TypeName System.Windows.Forms.Label
$Button_User.Add_Click({
    $MainWindow.Controls.Add($ComboBox)
    $Label_User_ItemContent = New-Object -TypeName System.Windows.Forms.Label
    $Button_Check_TEST.Add_Click({
        $Label_User_ItemContent.Text = (Get-ADUser -Identity 
        $ComboBox.SelectedItem).SamAccountName
    )}
})

Here is the whole script in working condition now

$font = New-Object -TypeName System.Drawing.Font("Times New Roman", 18, [System.Drawing.FontStyle]::Bold)

$MainWindow = New-Object -TypeName System.Windows.Forms.Form
$MainWindow.Text = 'PIM v10 Administrator Window'
$MainWindow.Width = 600
$MainWindow.Height = 555
$MainWindow.AutoSize = $true

$Button_User = New-Object -TypeName System.Windows.Forms.Button
$Button_User.Location = New-Object -TypeName System.Drawing.Size(25, 25)
$Button_User.Size = New-Object -TypeName System.Drawing.Size(200, 75)
$Button_User.Text = 'User'
$Button_User.Font = $font

$MainWindow.Controls.Add($Button_User)

$ComboBox = New-Object -TypeName System.Windows.Forms.ComboBox
$Label_User_ItemContent = New-Object -TypeName System.Windows.Forms.Label

$Button_User.Add_Click({
    $Label_User = New-Object -TypeName System.Windows.Forms.Label
    $Label_User.Text = 'Given Name:'
    $Label_User.Location = New-Object -TypeName System.Drawing.Point(250, 50)
    $Label_User.AutoSize = $true

    $MainWindow.Controls.Add($Label_User)


    $Label_User_ItemContent.Text = ''
    $Label_User_ItemContent.Location = New-Object -TypeName System.Drawing.Point(250, 100)

    $MainWindow.Controls.Add($Label_User_ItemContent)


    $ComboBox.Width = 300
    $ComboBox.Location = New-Object -TypeName System.Drawing.Point(250, 25)

    $Users = Get-ADUser -Filter * | Where-Object {$_.SamAccountName -match '^adminA'}
    $MainWindow.Controls.Add($ComboBox)
    ForEach ($User in $Users){
        $ComboBox.Items.Add($User.SamAccountName)
    }
    $MainWindow.Controls.Add($ComboBox)
    $ComboBox.SelectedIndex = 0   
    $Button_Check_TEST = New-Object -TypeName System.Windows.Forms.Button
    $Button_Check_TEST.Location = New-Object -TypeName System.Drawing.Size(350, 150)
    $Button_Check_TEST.Size = New-Object -TypeName System.Drawing.Size(150, 50)
    $Button_Check_TEST.Text = 'Check'

    $MainWindow.Controls.Add($Button_Check_TEST)

    $Button_Check_TEST.Add_Click({
        Try{
            $Label_User_ItemContent.Text = (Get-ADUser -Identity $ComboBox.SelectedItem).SamAccountName
        }
        Catch{
            Write-Verbose -Verbose $_.Exception.Message
        }
    })

    if (-not ($ComboBox.SelectedItem -eq $null)){
        $Label_User_ItemContent.Text = (Get-ADUser -Identity $ComboBox.SelectedItem).SamAccountName
    }
    else {
        Write-Host -Object "Object is null"
    }
})
$MainWindow.ShowDialog()

Upvotes: 1

Related Questions