Home > Software design >  WinForm not loading the first time
WinForm not loading the first time

Time:12-22

I am writing a program using PowerShell WinForms. For example, the "Login" part of the program.

#CREDENTIAL CREATE - LOGIN AND PASSWORD INPUT
############################################


#APP FOUNDATION
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing


#Login_Form
$Login_Form                                         = New-Object -TypeName System.Windows.Forms.Form
$Login_Form.ClientSize                              = (New-Object -TypeName System.Drawing.Size -ArgumentList @([System.Int32]340,[System.Int32]110))
$Login_Form.Text                                    = [System.String]'Login_Form'
$Login_Form.add_Load($Login_Form_Load)
$Login_Form.ResumeLayout($false)
$Login_Form.PerformLayout()
$Login_Form.SuspendLayout()
$Login_Form.FormBorderStyle                         = "FixedDialog"

#Login_Label_User
$Login_Label_User                                   = (New-Object -TypeName System.Windows.Forms.Label)
$Login_Label_User.Location                          = (New-Object -TypeName System.Drawing.Point -ArgumentList @([System.Int32]12,[System.Int32]9))
$Login_Label_User.Name                              = [System.String]'Login_Label_User'
$Login_Label_User.Size                              = (New-Object -TypeName System.Drawing.Size -ArgumentList @([System.Int32]100,[System.Int32]18))
$Login_Label_User.TabIndex                          = [System.Int32]3
$Login_Label_User.Text                              = [System.String]'Login:'
$Login_Label_User.UseCompatibleTextRendering        = $true

#Login_TextBox_User
$Login_TextBox_User                                 = (New-Object -TypeName System.Windows.Forms.TextBox)
$Login_TextBox_User.Location                        = (New-Object -TypeName System.Drawing.Point -ArgumentList @([System.Int32]12,[System.Int32]30))
$Login_TextBox_User.Name                            = [System.String]'Login_TextBox_User'
$Login_TextBox_User.Size                            = (New-Object -TypeName System.Drawing.Size -ArgumentList @([System.Int32]224,[System.Int32]21))
$Login_TextBox_User.TabIndex                        = [System.Int32]0
$Login_TextBox_User.Text                            = ((Get-ADDomain).name   "\")
$Login_TextBox_User.add_TextChanged($Login_TextBox_User_TextChanged)

#Login_TextBox_Password
$Login_TextBox_Password                             = (New-Object -TypeName System.Windows.Forms.TextBox)
$Login_TextBox_Password.Location                    = (New-Object -TypeName System.Drawing.Point -ArgumentList @([System.Int32]12,[System.Int32]74))
$Login_TextBox_Password.Name                        = [System.String]'Login_TextBox_Password'
$Login_TextBox_Password.Size                        = (New-Object -TypeName System.Drawing.Size -ArgumentList @([System.Int32]187,[System.Int32]21))
$Login_TextBox_Password.TabIndex                    = [System.Int32]1
$Login_TextBox_Password.Text                        = [System.String]''
$Login_TextBox_Password.PasswordChar                = '*'

#Login_Button_Enter
$Login_Button_Enter                                 = (New-Object -TypeName System.Windows.Forms.Button)
$Login_Button_Enter.Location                        = (New-Object -TypeName System.Drawing.Point -ArgumentList @([System.Int32]251,[System.Int32]74))
$Login_Button_Enter.Name                            = [System.String]'Login_Button_Enter'
$Login_Button_Enter.Size                            = (New-Object -TypeName System.Drawing.Size -ArgumentList @([System.Int32]75,[System.Int32]21))
$Login_Button_Enter.TabIndex                        = [System.Int32]2
$Login_Button_Enter.Text                            = [System.String]'ENTER'
$Login_Button_Enter.UseCompatibleTextRendering      = $true
$Login_Button_Enter.UseVisualStyleBackColor         = $true
$Login_Button_Enter.add_Click($Login_Button_Enter_Click)

#Login_Button_ShowHide
$Login_Button_ShowHide                                 = (New-Object -TypeName System.Windows.Forms.Button)
$Login_Button_ShowHide.Location                        = (New-Object -TypeName System.Drawing.Point -ArgumentList @([System.Int32]205,[System.Int32]74))
$Login_Button_ShowHide.Name                            = [System.String]'Login_Button_ShowHide'
$Login_Button_ShowHide.Size                            = (New-Object -TypeName System.Drawing.Size -ArgumentList @([System.Int32]32,[System.Int32]21))
$Login_Button_ShowHide.TabIndex                        = [System.Int32]2
$Login_Button_ShowHide.Text                            = [System.String]'SHOW'
$Login_Button_ShowHide.UseCompatibleTextRendering      = $true
$Login_Button_ShowHide.UseVisualStyleBackColor         = $true
$Login_Button_ShowHide.add_Click($Login_Button_ShowHide_Click)

#Login_Label_Password
$Login_Label_Password                               = (New-Object -TypeName System.Windows.Forms.Label)
$Login_Label_Password.Location                      = (New-Object -TypeName System.Drawing.Point -ArgumentList @([System.Int32]12,[System.Int32]54))
$Login_Label_Password.Name                          = [System.String]'Login_Label_Password'
$Login_Label_Password.Size                          = (New-Object -TypeName System.Drawing.Size -ArgumentList @([System.Int32]100,[System.Int32]17))
$Login_Label_Password.TabIndex                      = [System.Int32]4
$Login_Label_Password.Text                          = [System.String]'Password:'
$Login_Label_Password.UseCompatibleTextRendering    = $true
$Login_Label_Password.add_Click($Label2_Click)

#Form.Controls
$Login_Form.controls.AddRange(@($Login_Label_Password,$Login_Label_User,$Login_Button_Enter,$Login_Button_ShowHide,$Login_TextBox_Password,$Login_TextBox_User))

#Login_Button_Enter Click logic    
$Login_Button_Enter_Click = {
    
    $Script:username                                = $Login_TextBox_User.Text
    $Script:password                                = $Login_TextBox_Password.Text
    $Script:secstr                                  = New-Object -TypeName System.Security.SecureString
    $Script:password.ToCharArray() | ForEach-Object {$secstr.AppendChar($_)}
    $Script:cred                                    = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $secstr
    $Login_Form.Close()
}

#Login_Button_ShowHide Click logic 
$Login_Button_ShowHide_Click = {

    if($Script:Login_TextBox_Password.PasswordChar -eq '*') {
    
        $Script:Login_TextBox_Password.PasswordChar            = 0
        $Login_Button_ShowHide.Text                            = [System.String]'SHOW'
    
    }
    
    elseif($Login_TextBox_Password.PasswordChar -eq 0) {
        $Login_Button_ShowHide.Text                            = [System.String]'HIDE' 
        $Script:Login_TextBox_Password.PasswordChar            = "*"
    
    
    }

}




#START APPLICATION

[void]$Login_Form.ShowDialog()

When I run the script for the first time, the window and everything else is shown correctly, but the buttons and logic do not work. For everything to work fine, I need to run it a second time.

How do I make everything work the first time I start it? I've tried everything that is possible already. I do not understand what is wrong.

CodePudding user response:

PowerShell is a largely interpreted language - statements are executed in line order.

You therefore need to define the event action scriptblocks before you can assign them to the respective event handlers, otherwise you're just assigning $null to the event handlers, which is why none of your buttons work.

# define the scriptblock that's supposed to handle the event action...
$Login_Button_ShowHide_Click = {
    if($Script:Login_TextBox_Password.PasswordChar -eq '*') {
        $Script:Login_TextBox_Password.PasswordChar            = 0
        $Login_Button_ShowHide.Text                            = [System.String]'SHOW'
    }
    elseif($Login_TextBox_Password.PasswordChar -eq 0) {
        $Login_Button_ShowHide.Text                            = [System.String]'HIDE' 
        $Script:Login_TextBox_Password.PasswordChar            = "*"
    }
}

#Login_Button_ShowHide
$Login_Button_ShowHide                                 = (New-Object -TypeName System.Windows.Forms.Button)
$Login_Button_ShowHide.Location                        = (New-Object -TypeName System.Drawing.Point -ArgumentList @([System.Int32]205,[System.Int32]74))
$Login_Button_ShowHide.Name                            = [System.String]'Login_Button_ShowHide'
$Login_Button_ShowHide.Size                            = (New-Object -TypeName System.Drawing.Size -ArgumentList @([System.Int32]32,[System.Int32]21))
$Login_Button_ShowHide.TabIndex                        = [System.Int32]2
$Login_Button_ShowHide.Text                            = [System.String]'SHOW'
$Login_Button_ShowHide.UseCompatibleTextRendering      = $true
$Login_Button_ShowHide.UseVisualStyleBackColor         = $true

# ... _before_ assigning it to handlethe event
$Login_Button_ShowHide.add_Click($Login_Button_ShowHide_Click)

Repeat for all the scriptblocks assigned as event handlers - either move them all to the top of the script, or, move all the .add_<EventName>() calls to the bottom, just before launching the GUI:

# Rest of script goes here ...

# register all event handlers
$Login_TextBox_User.add_TextChanged($Login_TextBox_User_TextChanged)
$Login_Button_Enter.add_Click($Login_Button_Enter_Click)
$Login_Button_ShowHide.add_Click($Login_Button_ShowHide_Click)

# start app
[void]$Login_Form.ShowDialog()
  • Related