Here I will post problems I and my colleagues met and solutions we found.

Thursday, April 10, 2008

BindingComplete, Exception and DevExpress TextEdit

In our current application we are using CSLA and DevExpress.

While CSLA provides validation rules, they allow to continue data modification even when some property has incorrect value. What I wanted to achieve was little bit different. I wanted to not allow assign incorrect values. The logical approach for me was to throw exception in property setter. But then it took me sometime to figure out how to handle this exception.

DevExpress TextEdit just return "Invalid value" as ErrorText. The exception I raised was just lost. After researching he subject I finally understood how it works.

1. When data assigned to control, it calls OnValidating method.
2. The method puts data to the object through binding
3. Exception raised in property setter
4. This exception is caught by Binding object itself
5. If FormattingEnabled property of Binding object is set to true, then exception is not raised again. Instead, BindingComplete event is raised
6. Cancel is set to true and that value returned to OnValidating
7. Here is some specifics for TextEdit (or BaseEdit for that matters), it has InvalidValue event, but there is no information about exception available, it just puts "Invalid Value" to ErrorText.

So, final solution for me was
1. Since I use BindingSource object, I handle BindingSouce.BindingComplete event with this code


public virtual void bindingSource_BindingComplete(object sender, BindingCompleteEventArgs e)
{
if (e.BindingCompleteState == BindingCompleteState.Exception)
{
MessageBox.Show(MainForm.MainForm, e.ErrorText, Properties.Messages.labelError, MessageBoxButtons.OK, MessageBoxIcon.Error);
e.Binding.ReadValue();
}
}

Than for InvalidValue event I have


private void BaseEditInvalidValueHandler(object sender, DevExpress.XtraEditors.Controls.InvalidValueExceptionEventArgs e)
{
if ((e.Exception is WarningException) && (e.Exception.InnerException == null))
e.ExceptionMode = DevExpress.XtraEditors.Controls.ExceptionMode.NoAction;
else
e.ExceptionMode = DevExpress.XtraEditors.Controls.ExceptionMode.ThrowException;
}



And of cause, there is topic at MSDN for that, http://msdn2.microsoft.com/en-us/library/k26k86tb.aspx

Update:
BindingSourceRefresh component from CSLA handles refreshing in BindingComplete event

3 comments:

Anonymous said...

Hi

This was very helpfull. Where and how do you hookup to the BaseEdit InvalidValue event. I have no instance of BaseEdit.

Maxim Alexeyev said...

You are welcome.

I don't quite understand your question. The problem I was solving was specific for DevExpress TextEdit control, which does have InvalidValue event, which is defined at BaseEdit level.

Maxim Alexeyev said...

I just realized that there is BindingSourceRefresh component in CSLA that handles this problem with refreshing data in BindingComplete event