Introduction to Data Binding


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.

[5] I reviewed and liked Brian Noyes's book Data Binding with Windows Forms 2.0 : Programming Smart Client Data Applications with .NET (Microsoft Net Development Series) (Addison-Wesley, 2006; ISBN 032126892X). Peter and I agree that it's a must-read for those who need more details on the inner workings of data binding.

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 Binding

When 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.

  • DataSource: This property points to the "source" of the data. In data access applications, this property is usually set to a populated DataTable or the DataView returned by the DefaultView property.

  • DisplayMember: When working with a complex bound control that displays only one column (like a ComboBox or ListBox) or a simple bound control, you must set the DataMember to address a specific column in the data sourceby name.

  • ValueMember: In some cases, I bind to a DisplayMember like "StateName" and a ValueMember like "StateCode" that contains the encoded value that corresponds to the display member. This way, users can see and select an English word like "Washington" while the underlying code uses the ValueMember value "WA" behind the scenes.

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.


1.

Click on the TextBox or other control you wish to bind to. Yes, this can be any control, including the Form itself.

2.

Press F4 or open the object's property page.

3.

Click on "(DataBindings)" in the property page, and then click on the ellipsis (...) after "Advanced". This opens the Formatting and Advanced Binding dialog (as shown in Figure 7.8).

4.

Select the control property to bind using the drop-down list (as shown in Figure 7.8) and navigate to the correct Data Source. Yes, there can be several of these as your project increases in complexity. Make sure you choose the right one.

5.

Next, set any property formatting and whether or not you want the bound control to attempt to update the data via a visible TableAdapter Update method (as shown in Figure 7.9).

Figure 7.9. Data binding using the Visual Studio Properties page.


6.

Click "OK". At this point, the Visual Studio code generator takes over. It adds code to the Form Load event handler, which generates the following three controls and adds them to the Tool Tray on your form:

  • A named DataSet instance that addresses the selected Data Source

  • A named BindingSource instance (as I discuss later in this chapter)

  • A named TableAdapter instance

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:

  • Initial rowset population: D&D creates the needed DataSet and TableAdapter instances and generates code to run the Fill or GetTable methods.

  • Binding: D&D generates the needed binding classes and sets the appropriate data binding properties (as shown in Figure 7.8).

  • Navigation: Whether binding simple or complex controls, D&D generates a BindingNavigator that includes navigation buttons. The BindingNavigator is tied directly to a CurrencyManager class (for list and rowset data sources) that provides the "move" methods to navigate between rows. I discuss this class later in this chapter.

  • Query parameter management: If the query you're executing uses input parameters, the D&D code generators create a ToolStrip control to capture and label these parameters.

  • Update management: Your UI needs some mechanism to refill once parameters change and when new data is to be added or changed data needs to be committed to the database. The D&D code generator adds buttons to the ToolStrip that point to your data management functions.




Hitchhiker's Guide to Visual Studio and SQL Server(c) Best Practice Architectures and Examples
Hitchhikers Guide to Visual Studio and SQL Server: Best Practice Architectures and Examples, 7th Edition (Microsoft Windows Server System Series)
ISBN: 0321243625
EAN: 2147483647
Year: 2006
Pages: 227

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net