Before I wade into the Toolbox controls used to manage data binding, let's discuss a few points on data "binding" that can make the process of knowing how and when to use these Toolbox controls a bit easier. Since there are better, more in-depth sources of information on data binding,[5] I'm not going to go very deep here, but I hope to clear up some of the fundamental mysteries. The binding mechanism implemented by the Framework is another one of those generic blocks of code designed to bind to virtually anything from arrays to small farm animals with parental consent. To stay focused, I'm going to stick to binding to ADO.NET classes like the DataTable and the DataView it exposes.
Binding simply means connecting one or more control properties with data source valuesin other words, showing stuff from the database and posting the changes made in the UI back to the data source so it can be posted back to SQL Server. The .NET Framework binding functions include posting incoming data to specified bound control properties (like the TextBox.Text) as it arrives at the data source (usually a DataTable or a TableAdapter, but a DataReader can be bound in ASP.NET applications, at least to some extent), refreshing the control(s) when the data source changes, and saving the changes back to the data source when your code determines that the user is done editing. Ever since Visual Basic V1.0, Microsoft (and control vendors) has been struggling with data bindingit's been a tough nut to crack. The BindingSource control and the classes that support it behind the scenes are the latest attempt at an easier-to-use binding interface. Typically, these binding classes add another layer between the sources of data like TableAdapter, DataTable, and DataView instances, and more specialized data sources such as ArrayList instances. For ASP.NET applications, data binding has improved quite a bit, in that it now supports full-duplex binding. That is, when data binding is half-duplex, it means that data flows from the bound data source (the DataTable) to the bound controls (like a DataGridView or TextBox). However, changes to the bound controls are not automatically posted to the DataSource. In ASP 1.1 and earlier versions, developers had to write code to move changes out of bound controls to the underlying "bound" data source. In 2.0, the Framework binding infrastructure supports full-duplex data binding. This means changes committed to bound controls are automatically posted to the data source. IMHO Based on the number of people who still get confused about data binding, I'm of the opinion that while the new data binding interface seems well received by those building tools, the average developer may indeed find this overwhelmingI did. To make matters worse, it's not that well documented in MSDN. All of the examples seem to work with object and array binding, which must be interesting for some, but hardly what most data access application developers will want to do. I'll try to simplify this discussion as much as possible, but I think you'll find that simply letting Visual Studio drag and drop generate the code might be the path of least resistance. Complex Versus Simple BindingWhen I bind to a control that can display only a single row from a single column, I use "simple" data binding. In this case, you typically bind to the visible property of the controllike the Text property of a TextBox. However, you can bind to any property of any control or to other objects as well. With simple binding, you have to manage "currency." That is, the control(s) bound to a data source (like a DataTable) can show only one row at a time. It's up to your code to position the current row pointer, know when you've reached the end or beginning of the rowset, and expose controls or other mechanisms to permit the user to navigate through the rowset. As I discussed earlier when demonstrating drag-and-drop data binding, Visual Studio automatically generates all of this code for you, if you let it. Tip You might use drag-and-drop binding to show what the underlying data binding should look like. When I bind to a control that's capable of displaying an entire rowset, I use "complex" data binding. In this case, I bind to the control's DataSource property to the data source (like a DataTable) and DataMember property to a specific column if the control shows only one column. For example, to bind to a DataGridView in a Windows Forms application, you simply set the DataSource property to the DataTable or DataView. However, when binding to a ListBox or ComboBox control, you must also set the DataMember property to the specific column to displayby name. This means you'll have to hard-code the column's name as a string into the DataMember property. Complex bound controls are responsible for completing rowset populationbut that's up to you with simple bound controls. This means complex bound controls read all of the rows from a DataReader or simply pull all of the rows out of the DataTable to populate its internal display elements. When binding to a DataReader (in ASP.NET), once rowset population is complete, the DataReader is closed. Nope, DataReader binding is not an option for Windows Forms applicationsyou'll need to load a DataTable from a DataReader beforehand and bind to the DataTable. Each Control object implements a collection of bindable elements (IBindableComponent), which permits you to bind any of the control's properties to a data source. An interesting use of this feature would be to bind a TextBox control's Text property to a DataTable column value, and the ReadOnly or the ForeColor properties to other data-driven columns to prevent the user from changing the valueand seeing that it's read-only based on the text color. Yes, each bound value can come from a different data source. Let's review the control properties that are used with data binding.
As the .NET Framework has evolved, Microsoft has further refined data binding so that as developers' skills evolved, they would continue to find easier ways to connect data with bound controls. The 2.0 Framework has taken a number of steps to make things simplersome of the more complex interfaces were hidden behind new objects like the BindingSource, and additional options were added to accommodate more sophisticated designs. IMHO, it's still pretty complicated, but the designers and drag-and-drop can eliminate all of this code for you if you still can't figure it out. Each .NET Framework control also implements a DataBindings collection. This collection can be populated in code (as shown in Figure 7.7). In this case, I added a DataBinding to each TextBox controlnaming the TextBox property I want to bind, the data source (a DataTable in this case), and the DataTable column's name. Figure 7.7. Coding simple binding from a DataTable to a set of TextBox controls.
The TextBox property and column name strings are not checked at design time. If you misspell any of the string parameters here, you're pooched and won't find out until you reach this code at runtimeif you do. Remember, a control can have more than one property bound to a data source. However, the Framework won't let you define more than one binding to the same property. Another approach to setting the DataBindings property is to use the Visual Studio UI property dialog (shown in Figure 7.8). Figure 7.8. Choosing a binding Data Source.
I discuss the generated code in the next section, when I tour the BindingSource class. Frankly, this process was pretty tedious, as I had to repeat it for each and every control to bind. Behind the scenes, this GUI "RAD" process simply generates the same code I just built above (more or less)using cut and paste. Another issue with this approach is that if you don't choose the right data source (and there can be many to choose from, even in a simple application), you won't see the right data in your bound controlsif you see any at all. The benefit to this approach is the ability to set the property format. Sure, that can be set in code as well, if you need that additional functionality. A disadvantage to this approach (in my mind) is the fact that when you use the UI to set up data binding, by default the Fill method is called in the Form Load event, so the user has to wait while the query is executed before the Form is visible. When you commit to this type of binding, the Visual Studio code generator writes a TableAdapter Fill call to the Form Load event, as shown in Figure 7.10. Figure 7.10. Visual Studio adds code to your Form_Load when you use Property page data binding.Yes, you can (and probably should) remove this line of code if you manage query execution yourself. This helps your Form load faster and gives your user the opportunity to set input parameters for the Fill query. IMHO The sample application ("Binding Source") on the DVD illustrates these points in a complete example. So what's missing? This seems pretty simple so far. Well, consider that I'm working with "simple" bound controls, and there is a list of other tasks that must dealt with somehow. Again, if you use drag-and-drop (D&D) data binding, many of these issues are handled automatically by generated code. If you find that this approach can't work in your situation, you'll need to take care of the following details that D&D handles automatically:
|