2

I have a custom form which is open as Form.ShowDialog()

This form acts as a confirmation form. It asks a question whether you want to accept or decline the previously entered input in ComboBox & TextBox.

If you click OK, the input is saved into Excel File.

If you click Cancel, the input is not saved.

The problem I am having is that:

When you click cancel. The form.ShowDialog() is closed. (Which is fine.)

But when the form.ShowDialog() is open again. It retains the focus on the Cancel Button. So if you try to confirm the entry with "Enter" key, you cancel it instead.

My question is. Why does the Form.ShowDialog() retain the focus on the buttons after closing?

The Form.ShowDialog() has accept button "OK" [tabindex = 1], and cancel button "Cancel" [tabindex = 2] which are set to Enter key, and Esc key.

(To note again)The focus of the buttons remains after closing the form.

The portion of the code using the Dialog:

    ElseIf ComboBoxBP.SelectedItem = ComboBoxBP.SelectedItem And TextBoxBP.Text = TextBoxBP.Text Then

        form.Label1.Text = ComboBoxBP.SelectedItem
        form.Label2.Text = TextBoxBP.Text
        form.ShowDialog()

        If form.DialogResult = Windows.Forms.DialogResult.Yes Then

            SiE()

        ElseIf form.DialogResult = Windows.Forms.DialogResult.No Then

            LabelBPBot.Text = "Canceled."

        End If

    End If
Ňɏssa Pøngjǣrdenlarp
  • 38,411
  • 12
  • 59
  • 178
Taffs
  • 143
  • 1
  • 2
  • 12

1 Answers1

5

When you use .ShowDialog() closing the form does not dispose of it as with a normal form. This is because once a Dialog "closes" it actually just hides so we can get info from it before it actually goes away.

The second issue is that forms are classes (it says so at the top of every one of them:)

Public Class Form1
    ...

So, instances of them should be created. VB allows Form1.Show or Form1.ShowDialog() to use a "default instance" and it is a shame that it does.

Combine these 2 tidbits and what you have is a case where the form you showed last time is still around in the same state as when you last used it, including the last focused control. You are only using a "fresh copy" of the form the first time, after that, you are just reusing the old instance. Remedy:

Using Dlg As New Form1             ' form1 is the class, dlg is the instance
   ... do stuff

   Dim res As DialogResult = Dlg.ShowDialog()

   If res = Windows.Forms.DialogResult.OK Then
       '... do stuff
   End If

End Using                          ' dispose of Dlg

Eventually, you will run into similar issues using the default instance of the other forms (LForm.Show). Just Say No to Default Form instances.

Ňɏssa Pøngjǣrdenlarp
  • 38,411
  • 12
  • 59
  • 178
  • I'll try this, and will get back at you. – Taffs Mar 21 '15 at 20:10
  • 1
    Thanks for the neat explanation, and how to fix it. – Taffs Mar 21 '15 at 20:12
  • @WelcomeOverflow... your solution finally help me... can be same done with : `Dim res As DialogResult = Form1.ShowDialog() : '*if dialogOK do stuff*' : Form1.Dispose()` or it's better way to use `Using/End Using` block? thx. – nelek Dec 22 '18 at 15:20