Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Closing the C# windows form by avoiding textbox validation

Tags:

c#

textbox

This is a winform C# question. I have a textbox with a validating event listener to validate the content of the textbox against a regular expression.

After the validation, if entered value is not proper,i am showing the messagebox and i am cancelling the event so that mouse cursor move back to the textbox which has improper value.

This is working fine when i move out from that textbox to other buttons/textboxes.

But when i enter improper value and close the form (with the close button on right top corner), it validates the textbox contents and throws up the messagebox and form doesnot close as i am cacelling the event.

The problem is, when I click the X button on the right top corner of the form, I don't want the validation to be fired because I am closing the form anyway. How can I do this?

I will post the code snippet as soon as possible.

like image 293
ananth joshi Avatar asked Apr 10 '13 08:04

ananth joshi


People also ask

What is close in C?

The close() function shall deallocate the file descriptor indicated by fildes. To deallocate means to make the file descriptor available for return by subsequent calls to open() or other functions that allocate file descriptors.

What does close 2 do in C?

close() closes a file descriptor, so that it no longer refers to any file and may be reused. Any record locks (see fcntl(2)) held on the file it was associated with, and owned by the process, are removed (regardless of the file descriptor that was used to obtain the lock).

What happens if you don't close C?

As long as your program is running, if you keep opening files without closing them, the most likely result is that you will run out of file descriptors/handles available for your process, and attempting to open more files will fail eventually.

When should you close a file in C?

A file needs to be closed after a read or write operation to release the memory allocated by the program. In C, a file is closed using the fclose() function. This returns 0 on success and EOF in the case of a failure. An EOF is defined in the library called stdio.


1 Answers

To use validating handlers such as the 'txtIPAddress_Validating()' handler below while being able to close the form without having to enter valid entries to do so, I do the following:

1) Initate validating handlers: From the control properties of the control you wish to activate validation for, double click the 'Validating' event from this control event list. A control event list is accessed by clicking this control's property sheet’s event (lightning looking) toolbar button. You can then enter the code in the automatically generated handler with a name combining both the name of the control and '_Validating'. The part of this handler where something is established as invalid can force valid entries by adding the 'e.Cancel = true' instruction.

For such validating method examples, See 'txtIPAddress_Validating()' and 'txtMaskBits_Validating()' code below. Do not get distracted by the complete validation mechanism of these specific examples. All you need to see and reproduce in your own code in order to force validation is to add the 'e.Cancel = true' instruction at the right place of your own validating method. That is when the value is identified to be invalid.

At this point the validation should work fine but any attempt to close the form will trigger validation which will stop and insist for valid values before being able to close the form. This is not always what you want. When it is not so, I continue with the following.

2) 'Cancel' button that also cancels (disables) all validations:

a) Place a regular 'Cancel' button on the form which is associated to a method such as the 'btnCancel_Click()' method below.

b) Before the regular 'this.close();' instruction, add the 'AutoValidate = AutoValidate.Disable;' instruction. This instruction disables all 'validating' triggers. Note that the 'btnCancel_Click' event is triggered before any validation is taking place. That is not so for the Form Closing events that will all execute after validating events. That is why that validation cannot be disabled from any of these Form Closing events.

c) For this 'Cancel' button to work correctly, you also need to set the 'CausesValidation' property of this 'Cancel' button to 'false'. This is necessary, otherwise clicking on this button will trigger the validation before validating can be disabled by the above 'AutoValidate = AutoValidate.Disable;' instruction.

At this point, you should be able to quit by clicking on the 'Cancel' button without having to first enter valid values. However, clicking the upper right "X" button of the form's window will still force validation.

3) Make the upper right "X" button also cancel validation:

The challenge here is to trap such "X" clicked event before validation is executed. Any attempt to do so through a Form Closing handler will not work because it is then too late once execution reaches such handler. However, the click of the "X" button can be captured promptly via overriding the WndProc() method and testing for a 'm.Msg == 0x10' condition. When that condition is true, the previously introduced 'AutoValidate = AutoValidate.Disable;' instruction can again be used to disable overall validation in that case as well. See the WndProc() method below for a code sample of such method. You should be able to copy and paste that method as is in your form's class.

At this point, both the 'Cancel' an "X" buttons should cancel valdations. However, the escape key that can be used to close a form does not. Such escape key is activated when the form's 'CancelButton' property is used to link this escape key to the form's 'Cancel' button.

4) Make the escape key also cancel validation:

Similar to the "X" button, the escape key can be captured by overriding an existingmethod. That is the ProcessDialogKey() method. One more time, the previously introduced 'AutoValidate = AutoValidate.Disable;' instruction can be used to disable overall validation for the escape key as well. See the ‘ProcessDialogKey()’ overridden method in the code below to see how this can be done. Here again, you should be able to copy and paste that method as is in your own form's class.

At this point you should be done!

Further considerations:

It is good to notice that the following two other ways to close the window should also work fine at this point. These two ways are:

  • The 'Close' option of the upper left window icon button.
  • Pressing Alt+F4 which triggers the same closing action as the above 'Close' option.

These two ways of closing the window started to also cancel validation once you introduced the "X" button capture mechanism described in point 3 above.

That is it for me for this so far. Hoping this helps!

My code sample below:

public partial class frmMyIP : Form
{
    public frmMyIP()
    {
          InitializeComponent();
    }

    // To capture the Upper right "X" click
    protected override void WndProc(ref Message m)
    {
        if (m.Msg == 0x10) // The upper right "X" was clicked
        {
            AutoValidate = AutoValidate.Disable; //Deactivate all validations
        }
        base.WndProc(ref m);
    }

    // To capture the "Esc" key
    protected override bool ProcessDialogKey(Keys keyData)
    {
        if (keyData == Keys.Escape)
        {
            AutoValidate = AutoValidate.Disable;
            btnCancel.PerformClick(); 
            return true;
        }
        return base.ProcessDialogKey(keyData);
    }
    public bool IsValidIP(string ipaddr)
    {
        string pattern = @"^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])"+
        @"(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$";

        Regex check = new Regex(pattern);
        bool valid = false;

        if (ipaddr == "")
        {
            valid = false;
        }
        else
        {
            valid = check.IsMatch(ipaddr, 0);
        }

        return valid;
    }

    private void txtIPAddress_Validating(object sender, CancelEventArgs e)
    {
        string address = txtIPAddress.Text;
        if (!IsValidIP(address))
        {
            MessageBox.Show("Invalid IP address!");
            e.Cancel = true;
        }
    }

    private void cmbMaskBits_Validating(object sender, CancelEventArgs e)
    {
        int MaskBitsValue = Convert.ToInt32(cmbMaskBits.Text);

        if (MaskBitsValue<1 || MaskBitsValue>30)
        {
        MessageBox.Show("Please select a 'Mask Bits' value between 1 and 30!");
        e.Cancel = true;
        }
    }

    private void btnCancel_Click(object sender, EventArgs e)
    {
        // Stop the validation of any controls so the form can close.
        // Note: The CausesValidation property of this <Cancel> button
        //       must also be set to false.

        AutoValidate = AutoValidate.Disable;
        this.Close();
    }
like image 106
Sylvain Raymond Avatar answered Sep 18 '22 06:09

Sylvain Raymond