Validating event in databound controls

G

Guest

Hi,

I've created a custom control derived from TextBox, which internally parses
the Text to a decimal value (in the OnValidated method) and exposes this
value as a Value property.
The control handles invalid input in an overwritten OnValidating method by
setting the Cancel member of the CancelEventArgs parameter to true (and by
changing the background color of the control).

I now want to bind the Value property of my control to some class property.
When I do so, i get two issues:

First, if I set the update mode to DataSourceUpdateMode.OnValidation and
enter a value in my text box, I have to leave the textbox twice using TAB key
(so I must press TAB, go back to the text box and press TAB again) before the
value is accepted. When the update mode is
DataSourceUpdateMode.OnPropertyChanged, overything goes fine.

Second, If I enter a wrong value into the text box, the focus still moves on
to the next control instead of staying in my text box, although the form's
AutoValidate property is set to EnablePreventFocusChange.

I would like my databound control to behave like the other (non-bound)
controls. Do you have any ideas what's happening? Does the databinding
mechanism influence/bypass the normal validation cycle in any way? Should I
use another method to parse the Text property (and set my new Value property)?

Thank you in advance
 
B

Bart Mermuys

Hi,

Martin Stettner said:
Hi,

I've created a custom control derived from TextBox, which internally
parses
the Text to a decimal value (in the OnValidated method) and exposes this
value as a Value property.
The control handles invalid input in an overwritten OnValidating method by
setting the Cancel member of the CancelEventArgs parameter to true (and by
changing the background color of the control).

I now want to bind the Value property of my control to some class
property.
When I do so, i get two issues:

First, if I set the update mode to DataSourceUpdateMode.OnValidation and
enter a value in my text box, I have to leave the textbox twice using TAB
key
(so I must press TAB, go back to the text box and press TAB again) before
the
value is accepted. When the update mode is
DataSourceUpdateMode.OnPropertyChanged, overything goes fine.

Second, If I enter a wrong value into the text box, the focus still moves
on
to the next control instead of staying in my text box, although the form's
AutoValidate property is set to EnablePreventFocusChange.

I would like my databound control to behave like the other (non-bound)
controls. Do you have any ideas what's happening? Does the databinding
mechanism influence/bypass the normal validation cycle in any way? Should
I
use another method to parse the Text property (and set my new Value
property)?

I'm not sure how to reproduce your exact problem. But DataBinding does
attach an eventhandler to the Validating event inwhere it will push control
values to datasource values but only if they are changed (if the property
has a similar changed event).

1) If you are overriding OnValidating, then you should call
Base.OnValiditing at the end since this will trigger the Validating event
and a data push from control to source. Something like this seems to work:

public class Class1 : TextBox
{
private Decimal val;

public event EventHandler ValueChanged;

public Decimal Value
{
get { return val; }
set
{
if (val != value)
{
val = value;
Text = val.ToString();
if (ValueChanged != null)
ValueChanged(this, EventArgs.Empty);
}
}
}

protected override void OnValidating(System.ComponentModel.CancelEventArgs
e)
{
decimal result;
if (decimal.TryParse(Text, out result))
{
Value = result;
BackColor = System.Drawing.Color.White;
}
else
{
BackColor = System.Drawing.Color.Red;
e.Cancel = true;
}
base.OnValidating(e);
}
}

2) But if you would bind to a normal TextBox Text property, then
DataBinding will try to parse the Text into a Decimal also and if it fails
you can do something inside Binding.BindingComplete eventhandler:

textBox1.DataBindings["Text"].BindingComplete += new
BindingCompleteEventHandler(Form3_BindingComplete);

void Form3_BindingComplete(object sender, BindingCompleteEventArgs e)
{
if (e.BindingCompleteContext == BindingCompleteContext.DataSourceUpdate)
{
if (e.BindingCompleteState != BindingCompleteState.Success)
e.Binding.Control.BackColor = System.Drawing.Color.Red;
else
e.Binding.Control.BackColor = System.Drawing.Color.White;
}
}

For both cases to work properly you need to make sure formatting is enabled
(code or desinger) (Binding.FormattingEnabled).

HTH,
Greetings
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top