none
Enable OK Button when more Form Boxes are populated RRS feed

  • Question

  • Hi Scripting Guys,

    I would like to ask you how can I enable .NET form OK button only when both boxes (textBox and ListBox) are populated (or more boxes like ListBoxes and ComboBoxes), not just One box populated..

    I have found a peace of script:

    $textBox.add_TextChanged({$OKButton.Enabled = $textBox.Text})
    $listBox.add_SelectedIndexChanged({$OKButton.enabled = $listBox.Text})

    which can do it just for one box, but I need to enable OK button only when multiple boxes are populated.

    Here is the script:

    Add-Type -AssemblyName System.Windows.Forms
    Add-Type -AssemblyName System.Drawing

    # Form setup

    $form = New-Object System.Windows.Forms.Form
    $form.Text = 'Custom Form'
    $form.Size = New-Object System.Drawing.Size(400,350)
    $form.StartPosition = 'CenterScreen'
    $form.FormBorderStyle = 'Fixed3D'
    $form.MaximizeBox = $false

    # Buttons

    $OKButton = New-Object System.Windows.Forms.Button
    $OKButton.Location = New-Object System.Drawing.Point(100,270)
    $OKButton.Size = New-Object System.Drawing.Size(75,23)
    $OKButton.Text = 'OK'
    $OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
    $OKButton.Enabled = $false
    $form.AcceptButton = $OKButton
    $form.Controls.Add($OKButton)

    $CancelButton = New-Object System.Windows.Forms.Button
    $CancelButton.Location = New-Object System.Drawing.Point(200,270)
    $CancelButton.Size = New-Object System.Drawing.Size(75,23)
    $CancelButton.Text = 'Cancel'
    $CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
    $form.CancelButton = $CancelButton
    $form.Controls.Add($CancelButton)

    # Labels

    $label1 = New-Object System.Windows.Forms.Label
    $label1.Location = New-Object System.Drawing.Point(10,10)
    $label1.Size = New-Object System.Drawing.Size(230,20)
    $label1.Text = 'Name:'
    $form.Controls.Add($label1)

    $label2 = New-Object System.Windows.Forms.Label
    $label2.Location = New-Object System.Drawing.Point(10,80)
    $label2.Size = New-Object System.Drawing.Size(280,20)
    $label2.Text = 'Select Item:'
    $form.Controls.Add($label2)

    # TextBox

    $textBox = New-Object System.Windows.Forms.TextBox
    $textBox.Location = New-Object System.Drawing.Point(10,30)
    $textBox.Size = New-Object System.Drawing.Size(260,40)
    $textBox.Height = 40
    $form.Controls.Add($textBox)


    # Listbox Items


    $listBox = New-Object System.Windows.Forms.listBox
    $listBox.Location = New-Object System.Drawing.Point(10,100)
    $listBox.Size = New-Object System.Drawing.Size(260,40)
    $listBox.Height = 80
    [void] $listBox.Items.Add('Item1')
    [void] $listBox.Items.Add('Item2')
    [void] $listBox.Items.Add('Item3')
    [void] $listBox.Items.Add('')
    $listBox.SelectionMode = 'MultiExtended'
    $form.Controls.Add($listBox)


    # Enable OK Button when boxes are populated


    $textBox.add_TextChanged({$OKButton.Enabled = $textBox.Text})
    $listBox.add_SelectedIndexChanged({$OKButton.enabled = $listBox.Text})


    $form.Topmost = $true

    $result = $form.ShowDialog()

    if ($result -eq [System.Windows.Forms.DialogResult]::OK)
    {
        $x = $textBox.Text
        $x

        $y = $listBox.SelectedItem
        $y
    }

    Thank you very much.

    Martin



    • Edited by Little Cub Tuesday, October 8, 2019 8:52 AM
    Monday, October 7, 2019 4:24 PM

Answers

  • I have found solution for my script with multiple textboxes (the principle is very simple, and is the same for listboxes, comboboxes, listviews.., just specific methods and properties must be applied).

    The trick is, that in the time of the event, when textbox (or listbox..) change occur, both (or multiple) conditions inside the add_TextChanged (or add_SelectedIndexChanged) method must be met. If I use event handler for the first textbox, and start filling the listboxes/textboxes.. from the last one to the first one, I meet the multiple conditions (in that event time), and the one event handler with conditions is enough.

    But when I want, that somebody can fill the form from any random textboxes/listviews, I must use event handlers for each textbox/listbox with all conditions...

    This example for my script above make it clear:

    $textBox.add_TextChanged({$OKButton.Enabled = (($textBox.Text) -and ($listBox.SelectedItem))})
    $listBox.add_SelectedIndexChanged({$OKButton.enabled = (($textBox.Text) -and ($listBox.SelectedItem))})

    So if you want to enable OKButton, depending on more than one "box", you need to define as many event handlers, as many "boxes" the OKButton would depend on to (with corresponding conditions inside the methods).

    I will be happy, if the solution would be helpful for anybody, who is trying with no luck.



    • Marked as answer by Little Cub 22 hours 26 minutes ago
    • Edited by Little Cub 22 hours 1 minutes ago
    22 hours 26 minutes ago

All replies

  • Use the validated event on all controls that need to be selected. I use the same validation code on all controls abnfd have it check the controls. When all are correct then enable the button else disable the button.


    \_(ツ)_/

    Monday, October 7, 2019 4:45 PM
  • Thank you jrv for your reply. I know what you mean, I have tried a lot of possibilities to implement this advice with no success. Could you please show, how exactly should events validation in my example look like, and how should "when all are correct" look like? Thank you very much.
    Tuesday, October 8, 2019 10:28 AM
  • I don't have any simple example code right now. All code I have is to complicated to use as an example.

    Use you search engine to find discussions about forms validation.

    The simple answer is to add a validated event to each control that needs to be validated.

    To validate a textbox:

    $validate = {
         if ( <tests to perform){
               # test passed
               $button.Enabled = $true
         }else{
               $button.Enabled = $false
        }
    }
    
    $textbox.add_Validated($validate)
    # add same code to other controls to validate


    \_(ツ)_/


    • Edited by jrv Tuesday, October 8, 2019 3:21 PM
    Tuesday, October 8, 2019 3:18 PM
  • I have found solution for my script with multiple textboxes (the principle is very simple, and is the same for listboxes, comboboxes, listviews.., just specific methods and properties must be applied).

    The trick is, that in the time of the event, when textbox (or listbox..) change occur, both (or multiple) conditions inside the add_TextChanged (or add_SelectedIndexChanged) method must be met. If I use event handler for the first textbox, and start filling the listboxes/textboxes.. from the last one to the first one, I meet the multiple conditions (in that event time), and the one event handler with conditions is enough.

    But when I want, that somebody can fill the form from any random textboxes/listviews, I must use event handlers for each textbox/listbox with all conditions...

    This example for my script above make it clear:

    $textBox.add_TextChanged({$OKButton.Enabled = (($textBox.Text) -and ($listBox.SelectedItem))})
    $listBox.add_SelectedIndexChanged({$OKButton.enabled = (($textBox.Text) -and ($listBox.SelectedItem))})

    So if you want to enable OKButton, depending on more than one "box", you need to define as many event handlers, as many "boxes" the OKButton would depend on to (with corresponding conditions inside the methods).

    I will be happy, if the solution would be helpful for anybody, who is trying with no luck.



    • Marked as answer by Little Cub 22 hours 26 minutes ago
    • Edited by Little Cub 22 hours 1 minutes ago
    22 hours 26 minutes ago
  • It is significantly easier and more normal to added the same validation event to all "Validated" events of all involved controls. After all controls have been validated the button will be enabled. It only requires one piece of code.

    $validateControls = {$OKButton.Enabled = $textbox1.Text -and $textbox2.Text -and $listbox.SelectedItem …}

    Add this to the validated event of all controls.


    \_(ツ)_/

    20 hours 12 minutes ago