2

I have set up a separate script for my form elements in powershell and am using dot-sourcing to link the two together. I am calling the text box function and this function should pass the user's input back to the original script but it doesn't.

---------- First Script - being used to call ---------- 
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") 
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") 


#---------- Overall Form Config ----------#
$form = New-Object System.Windows.Forms.Form
$form.Text = "New Service Account"
$form.Size = New-Object System.Drawing.Size(300,300) 
$form.StartPosition = "CenterScreen"



#---------- Account Name Field ----------#

."C:\Temp\include.ps1"
formLabel -labLocW 10 -labLocH 20 -labSizeW 280 -labSizeH 30 -labText "Enter SVC Account Name (Do Not Include SVC_)"
$a = formTextBox -tboxLocW 10 -tboxLocH 50 -tboxSizeW 260 -tboxSizeH 30
$b = formTextBox -tboxLocW 10 -tboxLocH 100 -tboxSizeW 260 -tboxSizeH 30
#$ok = formOKBut -okLocW 100 -okLocH 120 -okSizeW 60 -okSizeH 30 -okText "OK"

    $OKButton = New-Object System.Windows.Forms.Button
    $OKButton.Location = New-Object System.Drawing.Point(100,120)
    $OKButton.Size = New-Object System.Drawing.Size(60,30)
    $OKButton.Text = "OK"
    $OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
    $form.AcceptButton = $OKButton
    $form.Controls.Add($OKButton)


if($okbutton.Clicked){
    Write-Host $a

}

#---------- Show Form ----------#
$showForm = $form.ShowDialog() 


---------- Dot Script include ---------- 
function formTextBox($tboxLocW,$tboxLocH,$tboxSizeW,$tboxSizeH) {
    $textBox = New-Object System.Windows.Forms.TextBox
    $textBox.Location = New-Object System.Drawing.Point($tboxLocW,$tboxLocH) 
    $textBox.Size = New-Object System.Drawing.Size($tboxSizeW,$tboxSizeH) 
    $form.Controls.Add($textBox)
    $output = $textBox.Text
    return $output
}
2
  • 1
    Just: $OKButton.Add_Click({Write-Host $a}) ? Commented Mar 9, 2018 at 12:59
  • As an aside: your problem is unrelated to "dot-sourcing" another script (. "C:\Temp\include.ps1"). Commented Mar 9, 2018 at 13:07

1 Answer 1

2

In your formTextBox function, you're trying to return the text of a text-box control before the dialog has even been displayed, so that won't work.

Instead, return the control from the function, whose .Text property you can examine after the dialog has been closed:

function formTextBox($tboxLocW,$tboxLocH,$tboxSizeW,$tboxSizeH) {
    $textBox = New-Object System.Windows.Forms.TextBox
    $textBox.Location = New-Object System.Drawing.Point($tboxLocW,$tboxLocH) 
    $textBox.Size = New-Object System.Drawing.Size($tboxSizeW,$tboxSizeH) 
    $form.Controls.Add($textBox)
    return $textBox # Return the text box itself (the object)
}

# ...

# Create the text box, add it to the form, and store it in variable $a.
$a = formTextBox -tboxLocW 10 -tboxLocH 50 -tboxSizeW 260 -tboxSizeH 30

# ...

# Invoke the dialog and act on how it was closed.
if ($form.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
    $textA = $a.Text  # Get the text box' text now.
    Write-Verbose -Verbose "OK clicked: text box `$a contains: $textA"
} else {
    Write-Verbose -Verbose "Dialog was closed without clicking OK."
}

Furthermore, it looks like you were trying to react to the event of the OK button getting clicked with the following code, which also won't work, because again, it executes synchronously, before the dialog is ever shown:

if($okbutton.Clicked){  # DOESN'T WORK - event delegate needed instead
    Write-Host $a    
}

Instead, you need to set up an event handler (event delegate), which in PowerShell takes the form of <control>.add_<event-name>({ ... }); in the case at hand, we want to react to the Click event:

$OKButton.add_Click({
    param([object] $sender, [System.EventArgs] $evtArgs)
    Write-Verbose -Verbose "Button '$($sender.Text)' clicked."
})

The script block ({ ... }) will now be invoked when the button is pressed, whenever that occurs. The param() block declares the two arguments that are passed to your event delegate, although you can omit the declaration altogether if you don't need information about who originated the event ($sender) or the specifics of the event ($evtArgs), if any.


Note: To determine a given [System.Windows.Forms.Control] type's available events as well as the specific [System.EventArgs] subclass that is passed, you can use something like
New-Object System.Windows.Forms.Button | Get-Member -MemberType Event

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.