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