Return value from a button click

Welcome Forums General PowerShell Q&A Return value from a button click

Viewing 4 reply threads
  • Author
    Posts
    • #200660
      Participant
      Topics: 5
      Replies: 11
      Points: 67
      Rank: Member

      Hi again, still getting used to powershell.

      I’m trying to show a dialog with two buttons, and I want to return a value from each of them, and store it into a variable, I’ve been searching, and thats my approach (not working):

      Add-Type -AssemblyName System.Windows.Forms
      
      Add-Type -AssemblyName System.Drawing
      
      $form = New-Object System.Windows.Forms.Form
      
      $form.Text = 'One or Another?'
      
      $form.Size = New-Object System.Drawing.Size(300,200)
      
      $form.StartPosition = 'CenterScreen'
      
      $OneButton = New-Object System.Windows.Forms.Button
      
      $OneButton.Location = New-Object System.Drawing.Point(75,120)
      
      $OneButton.Size = New-Object System.Drawing.Size(75,23)
      
      $OneButton.Text = 'One'
      
      $form.Controls.Add($OneButton)
      
      $selection = $OneButton.Add_Click({
      
          $form.Close()
      
          return "One"
      
      })
      
      $AnotherButton = New-Object System.Windows.Forms.Button
      
      $AnotherButton.Location = New-Object System.Drawing.Point(150,120)
      
      $AnotherButton.Size = New-Object System.Drawing.Size(75,23)
      
      $AnotherButton.Text = 'Sense'
      
      $form.Controls.Add($AnotherButton)
      
      $selection = $AnotherButton.Add_Click({
      
          $form.Close()
      
          return "Another"
      
      })
      
      $form.ShowDialog()

      And the dialog is not closing on the button press, maybe is something so simple I’m not doing, but I don’t see it.

      Thanks 😀

    • #200903
      Senior Moderator
      Topics: 3
      Replies: 121
      Points: 638
      Helping Hand
      Rank: Major Contributor

      So, it looks like you’re trying to store the output of a scriptblock inside an .Add_Click() event into the $selection variable (line 23, 41), but this doesn’t really work in this way. One thing you should be aware of is that when you implement a scriptblock like this it executes as a child of the parent script, which means that you need to deal with scopes. Also, the attempt to assign to a variable on those lines is what’s preventing the dialog from closing.

      Instead, what you can do is assign the output value that you want to the variable inside the scriptblock, like this:

      #add assemblies
      Add-Type -AssemblyName System.Windows.Forms
      Add-Type -AssemblyName System.Drawing
      
      #define the form
      $form = New-Object System.Windows.Forms.Form
      $form.Text = 'One or Another?'
      $form.Size = New-Object System.Drawing.Size(300,200)
      $form.StartPosition = 'CenterScreen'
      
      #define the One button
      $OneButton = New-Object System.Windows.Forms.Button
      $OneButton.Location = New-Object System.Drawing.Point(75,120)
      $OneButton.Size = New-Object System.Drawing.Size(75,23)
      $OneButton.Text = 'One'
      
      $OneButton.Add_Click({
          New-Variable -Name selection -Value $($OneButton.Text) -Scope Script -Force
          $form.Close()
      })
      
      #define the Another button
      $AnotherButton = New-Object System.Windows.Forms.Button
      $AnotherButton.Location = New-Object System.Drawing.Point(150,120)
      $AnotherButton.Size = New-Object System.Drawing.Size(75,23)
      $AnotherButton.Text = 'Another'
      
      $AnotherButton.Add_Click({
          New-Variable -Name selection -Value $($AnotherButton.Text) -Scope Script -Force
          $form.Close()
      })
      
      #add the buttons to the form
      $form.Controls.Add($OneButton)
      $form.Controls.Add($AnotherButton)
      
      #display the form
      $form.ShowDialog()
      
      #display the result
      "Button $selection was pressed"

      Note the use of -Scope Script when the selection variable is defined (lines 18, 29 above) – this assures that the variable will be available to the parent script (otherwise the variable will be set only inside the scriptblock and then destroyed when the scriptblock finishes).

      Also note that the buttons still behave as they’re designed to within the normal functions of the Form Class. Specifically, the buttons still produce a DialogResult when clicked because that’s how System.Windows.Forms Buttons are designed to work. The default value is “None”, but it can be set to any of these values. The point is, you are adding an extra feature to the button click (setting the value of a variable) but you aren’t replacing the normal behavior of the button.

      You should also be aware that PowerShell is really .NET under the hood – all PowerShell cmdlets are just implementations of .NET classes (hence the term cmdlet rather than command). Essentially PowerShell is a scripting language that makes operating .NET a little easier/more straightforward than typing out .NET class instructions, but it is also an abstraction. Sometimes to get specific functionality you may need to use .NET directly (for example).

      There is another discussion of custom buttons in this thread which has some useful links and other information in it. In particular, Anybox looks really nice if you want a feature-rich dialog box creation tool. Also, here is a custom function called New-WPFMessageBox which implements some XML to control the message box design.
      You don’t have to re-invent the wheel to get this kind of functionality in PowerShell, but if you’re doing it for your own edification then take a look at the script for those examples to learn some new tricks. Finally, here is a short wiki article about GUI event handling with PowerShell: How to Add a PowerShell GUI Event Handler (Part 1).

      • This reply was modified 1 month, 4 weeks ago by grokkit. Reason: edited for clarity
    • #200960
      Participant
      Topics: 5
      Replies: 70
      Points: 326
      Helping Hand
      Rank: Contributor

      I have always used $Script:Selection = $($AnotherButton.Text) for scoping. Is there an advantage to New-Variable? Just curios and thanks.

    • #201459
      Senior Moderator
      Topics: 3
      Replies: 121
      Points: 638
      Helping Hand
      Rank: Major Contributor

      Is there an advantage to New-Variable?

      There’s not really a functional difference unless you want to apply one of the parameters for New-Variable (e.g. -Option ReadOnly). Otherwise it’s really just preference.

    • #201687
      Participant
      Topics: 5
      Replies: 11
      Points: 67
      Rank: Member

      Yeah, that works. Thank you very much, still adapting on my way back to Powershell. 😀

Viewing 4 reply threads
  • You must be logged in to reply to this topic.