24

Hi I have a form which contains of several textboxes and two buttons Cancel and Ok. These buttons are assigned to accept and cancel buttons properties in form. The problem is that I have to validate texts entered in all textboxes.

I want to do that if user click Ok button(which is acceptButton). So I wrote a function which is reponsible for validation and I fire this function if user click Ok button. The problem is that I can't stop form from closing even if validation function return false. It happens because of the fact that I assigned acceptbutto property to my Ok button. Is there any way to prevent form from closing if validation fails without removing acceptbutton properties ??

tshepang
  • 12,111
  • 21
  • 91
  • 136
exMode
  • 241
  • 1
  • 3
  • 4

5 Answers5

36

This is the working solution we use (and it's kinda compiled from other answers).

You just have to set the DialogResult to None to prevent the form from closing.

//form init, auto-generated code (this is the case described)
private void InitializeComponent()
{
    //....
    this.AcceptButton = btnOk;
    this.btnOk.DialogResult = DialogResult.OK;
    //....
}

//event handlers
private void btnOK_Click(object sender, EventArgs e)
{
    if (!Validate())
        this.DialogResult = DialogResult.None;
}

private void Form_FormClosing(object sender, FormClosingEventArgs e)
{
    if (this.DialogResult == DialogResult.None)
        e.Cancel = true;
}
Alex from Jitbit
  • 53,710
  • 19
  • 160
  • 149
8

In the Ok button click handler change DialogResult to DialogResult.None when validation fails

Vinay B R
  • 8,089
  • 2
  • 30
  • 45
7

One way could be to apply the validation in OnFormClosing event and cancel the action based upon validation result.

--EDIT--

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    if (this.DialogResult == DialogResult.OK)
    {
        if (!IsValid())
        {
            Info("Invalid data");
            e.Cancel = true;
        }
        else
        {
            Info("Valid data found, closing dialog");
        }
    }
    else if (this.DialogResult == DialogResult.Cancel)
    {
        Info("Just cancelling!");
    }
}

And you may call this.Close(); on Cancel/Ok events.

Alternatively, in your OK button implementation you can change the DialogResult of the button and set it to None;

acceptButton.DialogResult = DialogResult.None;
KMån
  • 9,896
  • 2
  • 31
  • 41
  • the first snipet works but it also prevents from from closing even if You click cancel button – exMode Sep 26 '10 at 14:20
  • @exMode: See my updated code based upon your comment. `Info()` is just a method that calls `MessageBox` – KMån Sep 26 '10 at 18:30
  • But listening on the Form close event means you set the dialogresult value, let the dialog post an event dispatch, then it gets canceled, and then the dialogresult of the form is changed back to none. Why the extra steps of listening to Form.Close? Just wait and set the value of DialogResult when it's validated, not every time. – Patrick Sep 28 '10 at 10:36
  • @Patrick: It does not mean *you set the dialogresult value*. When you press the cancel button the framework does that for you, that, changes the `DialogResult`'s state for you. Try it. – KMån Sep 28 '10 at 10:45
  • But it still means that the DialogResult on the form is set to that of the Button, even if you don't set it explicitly yourself, which leads to a few extra calls that should be unnecessary. And as a side note, if you have DialogResult set on the button you don't need to call `this.Close()` on the form. – Patrick Sep 28 '10 at 10:56
1

Do not set Button.DialogResult in the Designer or somewhere else (don't confuse with Form.DialogResult). In the Button's click handler do the validation and if successful set Form.DialogResult to DialogResult.OK and close the form.

private void OkBtn_Click(object sender, EventArgs e)
{
    if (isValid())
    { 
      this.DialogResult = DialogResult.OK;
      this.Close();
    }
}
seemoewe
  • 11
  • 1
1

Don't set the AcceptButton property in your Form and remove the DialogResult property from your button (set it to DialogResult.None instead).

You can set the DialogResult property of your form in your validation code instead.

 if (allFieldsValidated) {
     DialogResult = DialogResult.OK;
 }
Patrick
  • 17,669
  • 6
  • 70
  • 85
  • I was trying this approuch previously however this code doesn't work. If I click Ok button and validation returns true nothing happen, however if I click button Ok once more, form close itself. – exMode Sep 26 '10 at 14:39
  • @exMode: What do you mean nothing happens? Does it not go into validation? When you are done validating, can you not set `DialogResult` of the form to `DialogResult.OK` and have the Form close itself? – Patrick Sep 26 '10 at 15:59
  • I mean that form does't close even if validation returns true. Unofrtunatelly I can't resign from seting DialorResult.OK – exMode Sep 26 '10 at 16:30
  • But when the validation returns true, why can't you set the value of DialogResult? I do not understand what you mean by "I can't resign from seting", would you please rephrase? – Patrick Sep 26 '10 at 17:15
  • I set the dialogResult.Ok when validation returns true. However form doesn't close for the first time. I have to click Ok button once again – exMode Sep 26 '10 at 17:35
  • That seems strange. It seems like your setting the DialogResult of the Button and not the Form. Are you really setting the DialogResult of *the Form* that is your dialog to DialogResult.OK and not the Button that you click? – Patrick Sep 26 '10 at 18:14
  • You need to add a Close(); method to close the form. – John Hartley Oct 10 '14 at 04:48
  • @JohnHartley: Since when? – Patrick Oct 10 '14 at 09:25