Search code examples
c#winformscomboboxrevit-apidialogresult

A Button needs to be clicked twice to close a Dialog


I am trying to run a simple code. I have created a Form with a ComboBox (DropDownStyle = DropDown), which is empty in the beginning, it's filled with two when the DropDown is opened.
This Form also has 2 Buttons, one of them is the proceedButton Button sown in code.

In this block of code I am checking if the ComboBox is empty and if it, I am prompting user to select an Item from the ComboBox.
When the item is selected, I want to click proceedButton and the Form should close, but it this action takes a second click.

private void exitButton_Click(object sender, EventArgs e)
{
    exitButton.DialogResult = DialogResult.Cancel;
    Debug.WriteLine("Cancel was clicked");
    Close();
}

private void proceedButton_Click(object sender, EventArgs e)
{
    if (string.IsNullOrEmpty(comboBox1.Text))
    {
        MessageBox.Show("Nothing was selected, please try again!");
    }
    else
    {
        proceedButton.DialogResult = DialogResult.OK;
        Debug.WriteLine("Proceed was clicked");
    }
}

Do you know why is that?


Solution

  • Button Controls have a DialogResult property you can set to one of the DialogResult values.

    • Clicking a Button that has its DialogResult property set to a value that is not DialogResult.None, causes the Dialog to Close, also setting the value returned by Form.ShowDialog():

      DialogResult result = Form.ShowDialog().  
      

    The DialogResult property of Buttons is usually set in the Designer or in the Form Constructor (same thing).

    • When a Button with DialogResult = DialogResult.Cancel is clicked, the Dialog is closed. The same value is returned by Form.ShowDiaog().
    • The same applies to a Button with DialogResult = DialogResult.OK.

    So, set these properties in the Designer, remove Close() from the exitButton Button Click handler (this action is already performed automatically).

    • You need to click OK twice because the first click just sets the DialogResult property, which is then acknowledged and performs its default action only in the second click.

    In the error condition of the proceedButton Button Click handler, set this.DialogResult = DialogResult.None; to cancel the action, before you show the MessageBox.

    The code can then be changed in:

    private void exitButton_Click(object sender, EventArgs e)
    {
        Debug.WriteLine("Cancel was clicked");
    }
    
    private void proceedButton_Click(object sender, EventArgs e)
    {
        if (string.IsNullOrEmpty(comboBox1.Text)) {
            this.DialogResult = DialogResult.None;
            MessageBox.Show("Nothing was selected, please try again!");
        }
        else {
            Debug.WriteLine("Proceed was clicked");
        }
    }