jmcilhinney
Jan 1st, 2009, 11:22 PM
VB version here (http://www.vbforums.com/showthread.php?t=524817).
There seems to be a lot of misconception, misinformation and downright lack of knowledge where data-binding is concerned. I'm a big fan of data-binding. I use it at every opportunity and I suggest that everyone else do the same. To that end, I decided that it would be a good idea to start a thread dedicated to the topic.
I'll add posts over time dedicated to different aspects of data-binding and hopefully I can help dispel some of the misconceptions and increase the knowledge of those who would like to save themselves some time writing laborious code to shuffle data back and forth between business objects or other lists and their UI.
Before I begin, I should point out that data-binding is not a panacea. It is just one of the tools in your tool box. Use it when it will help you accomplish your goal, especially when it will save you time. That said, it won't always be the right tool for the job. A good developer will be able to recognise those occasions and write their own code to do the job.
Now, one of the things I hear people say is that data-binding doesn't offer the control that writing your own code. To those people I say that that's a crock. Data-binding offers tremendous power out of the box, plus you can customise many aspects of it to accomplish many different things. If a situation comes along that is too curly for data-binding you still have the freedom to write your own custom routines. That doesn't mean you shouldn't use data-binding for the meat and potatoes though.
The first genuine instalment will be arriving very soon.
jmcilhinney
Jan 1st, 2009, 11:35 PM
I've started some other threads lately that touch on some data-binding issues so I'll refer to them at various times through this thread.
First up, let's take a look at simple data-binding. Simple data-binding involves creating a Binding object, either implicitly or explicitly, to transfer data between a single property of a control and a single property of an object or list of objects. The link is created via the DataBindings property of the control. Here's an example:
1. Create a new WinForms project.
2. Add four TextBoxes in two rows of two, with textBox1 and textBox2 above textBox3 and textBox4.
3. Replace the code of your form with the following:using System;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private Person myPerson = new Person();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// Implicitly create a Binding between textBox1.Text and myPerson.FirstName.
this.textBox1.DataBindings.Add("Text", this.myPerson, "FirstName");
// Explicitly create a Binding between textBox2.Text and myPerson.FirstName.
this.textBox2.DataBindings.Add(new Binding("Text", this.myPerson, "LastName"));
// Implicitly create a Binding between textBox3.Text and myPerson.FirstName.
this.textBox3.DataBindings.Add("Text", this.myPerson, "FirstName", false, DataSourceUpdateMode.OnPropertyChanged);
// Explicitly create a Binding between textBox4.Text and myPerson.FirstName.
this.textBox4.DataBindings.Add(new Binding("Text", this.myPerson, "LastName", false, DataSourceUpdateMode.OnPropertyChanged));
}
}
public class Person
{
public string _firstName;
public string _lastName;
public string FirstName
{
get
{
return this._firstName;
}
set
{
this._firstName = value;
}
}
public string LastName
{
get
{
return this._lastName;
}
set
{
this._lastName = value;
}
}
}
}4. Run the project.
5. Navigate from control to control, editing values as you go.
Now, there are several things to note about the code and the application behaviour. The first is that making changes in textBox1 and textBox2 automatically updates textBox3 and texBox4 respectively, even though there's no code there that explicitly sets the Text property of any TextBox. That's what data-binding is for. This examples shows the usual two-way nature of data-binding. For instance, the Text property of textBox1 is bound to the FirstName property of our Person object. As a result, when you change the Text property of textBox1 the new data is pushed to the FirstName property of myPerson. The Text property of textBox3 is also bound to the FirstName property of myPerson though, so when that data is pushed to the data source from textBox1 it also gets pushed from the data source to textBox3, so we see it update in turn.
The next point to note is that I have declared the Person class with FirstName and LastName properties, not just fields (i.e. member variables). That is an essential part of data-binding. You cannot bind fields, only properties. There are various technical reasons for this that I will discuss at a later time but, for now, just accept that if you ever want to bind your own types you must expose data via properties.
The next point to note is when changes actually get pushed via the Binding. If you didn't notice the difference the first time, try running the app again. Type "Peter" into textBox1 and hit the Tab key. Notice that textBox3 remains blank until you navigate away from textBox1. Now type "Smith" into textBox2 and hit Tab. Note that textBox4 also doesn't update until you leave textBox2. Now type "Mary" into textBox3 and hit Tab. Notice that textBox1 updates as you type, rather than waiting for you to navigate away. Type "Jones" into textBox4 and notice that textBox2 also updates as you type.
Take a look at the code window and note the difference between the first two lines and the last two. Ignore the 'false' arguments as they aren't relevant at the moment but do pay attention to the last argument in the last two lines. In each case we're specifying the DataSourceUpdateMode of the Binding as OnPropertyChanged. This means that the data source will be updated with the new data as soon as the bound property of the control changes. That's why you see changes in textBox1 and textBox2 as soon as you type in textBox3 and textBox4 respectively. Each key press causes the Text property of the TextBox to change. That change immediately updates the data source, i.e. myPerson, which immediately updates the other bound control. The first two lines don't specify a DataSourceUpdateMode so they use the default value of OnValidated. That means that the data source isn't updated until the control is validated, which normally won't happen until the control loses focus. That's why textBox1 and textBox2 don't update the data source until you navigate away from them.
There are good reasons why you might want to choose one or the other of these DataSourceUpdateMode values. In many cases you will want the data source to be updated as soon as possible, in which case will want to use OnPropertyChanged. In most cases though, it's not really necessary to update the data source until the user has definitely finished entering data. For instance, if the data source is going to be used to search a database for matching records, you're only going to want to use the final value. If the user will enter the name "Peter" then the intermediate values of "P", "Pe", "Pet" and "Pete" are of no value so there's no point pushing them to the data source. There's also the potential for an intermediate value to be invalid, in which case is could be very bad to update the data source. For instance, if a property must have a non-empty value and the user deletes the current value before typing in a new one you don't want to display an error message telling them to enter a value.
The third available DataSourceUpdateMode is Never. You'd choose this if you wanted data from the data source to be pushed to the control but not vice versa. This is less common than the other two but certainly valid in some instances.
The last point to note is the difference between line 1 and line 2, as well as the similar difference between lines 3 and 4. In line 1 a Binding object is created implicitly by calling Add and passing the appropriate property values. In line 2 a Binding object is created explicitly with similar property values and then passed to Add. There's effectively no difference between the two. The overloads of the Binding constructor have exactly the same parameters as the overloads of the Add method. There's no specific advantage to one over the other except for the fact that the implicit option is slightly shorter. As such, I'd recommend using the implicit option in almost all cases.
I should also point out that simple data-binding can be done in the Windows Forms designer using the (DataBindings) property. A common and useful way to take advantage of this is to bind a control property to an application setting, i.e. a property of Properties.Settings.Default. That way, your control property will be set automatically at startup, when the application settings are loaded, and any changes you make will be automatically pushed back to the setting to be saved at shutdown.
Finally, I would recommend some MSDN reading to further improve your knowledge. I'd suggest that you start by reading the topic for the Control.DataBindings property and follow the links to the class overview for its type and then the member listing. I'd also suggest reading all about the System.Windows.Forms.Binding class.