Reputation: 16310
I have the following class:
public class MyClass
{
public int? Field1 { get; set; }
public int? Field2 { get; set; }
}
The textbox controls on the form are bound to an instance of this class through a BindingSource
, and the data source is update on the OnValidated
event.
However, when the textbox is empty, the property it's bound to is not being updated (the previous value is being displayed again):
So, on the controls' OnValidating
event I added the following:
int value;
bool ok = int.TryParse(((TextBox)sender).Text, out value);
if (!ok)
{
myClassInstance.Field1 = null;
}
Questions:
Is the above the normal behavior of the BindingSource
when the value of the TextBox
is empty?
Is it possible to have a generic method that I can call in my OnValidating
events. Something like:
OnValidatingMethod((TextBox)sender, x => x.Field1);
The above line of code obviously doesn't work because the object instance is not referenced. But I was wondering if something like that is possible? Maybe an extension to the class:
myClassInstance.SetProperty(((TextBox)sender).Text, x => x.Field1);
Upvotes: 2
Views: 1106
Reputation: 205629
The whole idea of data binding is to abstract the target from the source. If you create such event handlers, the abstraction is over.
What you see is not normal of course, but is result of a very old bugs kept for "backward compatibility". It has been fixed long time ago by adding additional properties to the Binding class, but again for backward compatibility the default values are set to mimic the old behavior.
The properties that you need to set to make it work as expected are FormattingEnabled
to true
, and NullValue
to ""
. I usually use one of the DataBindings.Add
or Binding
constructor overloads that allows specifying all that information, like this:
textBox.DataBindings.Add("Text", bs, "Field1", true, DataSourceUpdateMode.OnValidation, "");
Here is a full demo:
using System;
using System.Windows.Forms;
namespace Samples
{
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var form = new Form();
var textBox1 = new TextBox { Parent = form, Left = 16, Top = 16 };
var textBox2 = new TextBox { Parent = form, Left = 16, Top = textBox1.Bottom + 16 };
var bs = new BindingSource { DataSource = typeof(MyClass) };
textBox1.DataBindings.Add("Text", bs, "Field1", true, DataSourceUpdateMode.OnValidation, "");
textBox2.DataBindings.Add("Text", bs, "Field2", true, DataSourceUpdateMode.OnValidation, "");
bs.DataSource = new MyClass { Field1 = 1, Field2 = 2 };
Application.Run(form);
}
}
public class MyClass
{
public int? Field1 { get; set; }
public int? Field2 { get; set; }
}
}
Finally, if you really want to be involved in the parsing part, you should attach handler to Binding.Parse
event.
Upvotes: 1