Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cancelling databound control validating event doesn't suppress attempt to update data source

I'm not getting the behaviour I would expect for a TextBox bound to an integer property in a business object.

Here's what I did:

(1) Set the DataSourceUpdateMode, for the TextBox to: OnValidation.

(2) In the Validating event for the TextBox, set e.Cancel = True if Integer.TryParse fails.

(3) Add a handler to Binding.Parse and Binding.BindingComplete and place breakpoints in the handlers.

Run the application, put "asdasd" in the TextBox and tab out. Despite setting e.Cancel = True, the Parse and BindingComplete events are both raised. According to the documentation, setting e.Cancel = True should suppress any further logic.

I searched MSDN to find out why this happens but I can't find anything. Does any one know of where I can some details on this?

ETA: I added a handle to the Validated event as well. Here's the sequence of events:

Bad data:

(1) Validating. (I set e.Cancel = True)

(2) Parse

(3) BindingComplete

Good data:

(1) Validating

(2) Parse

(3) BindingComplete

(4) Validated

ETA2: A bit more info and a work-around.

The problem with this behaviour is if you have some validation that is not implemented in the property setter.

For instance, let's say my integer property has to be an odd number. I don't check for this in the property setter, so I do the check in the validating event.

As you can see, from the above behaviour, the value, as a legitimate integer, will be written to the data source, even if I cancel validation.

Despite the fact that the data source is updated, if you do set Cancel in the validating event, the Validated event will not be fired, so you can still prevent the user from progressing.

Work-Around::

To stop the data source updating, you need to validate in the Binding.Parse event, and throw an exception - which prevents Binding from completing successfully.

like image 271
Jules Avatar asked Nov 02 '09 13:11

Jules


1 Answers

Adding a call to CancelEdit seems to make the difference.

    private void textBox1_Validating(object sender, CancelEventArgs e)
    {
        bindingSource1.CancelEdit();
        e.Cancel = true;
    }
like image 114
helgeheldre Avatar answered Oct 21 '22 07:10

helgeheldre