Automate the development process with a free new tool
| Executive Summary: |
Learn how a free development tool can help you use Microsoft Visual Studio 2008 to automate the data binding process. The tool lets you wire up a variety of data sources (such as SQL Server) to a variety of user interfaces (such as Windows Presentation Foundation—WPF
Imagine my surprise when I opened Visual Studio 2008 and found no support for an important type of data binding—automatically wiring up a data source (such as SQL Server) and a Windows Presentation Foundation (WPF) window or page. I found the lack of support for this automation strange, especially considering that WPF is used to build rich UIs for Windows Vista applications.
My Tool to Automate Data Binding
So, I decided to write my own tool to automate data binding with Visual Studio 2008 and WPF. I wanted to create a tool that’s easy to use and generates maintainable and reliable code. I was looking for three quality improvements: Better efficiency for my team because we can perform automated tasks much faster. Better adherence to standards because everyone uses the same tools to generate code. Solid code that passes testing 95 percent of the time or better.
When I automate a process, I first figure out the pattern of the code I want to output. For instance, with WPF databinding you might find a code pattern that looks like this:
With ComboBox1 .IsSynchronizedWithCurrentItem = True .DisplayMemberPath = "CompanyName" .SelectedValuePath = "CompanyName" .ItemsSource = thisTableToBindDataDataView End With
You should test several different patterns manually to determine which ones are the most effective. You want patterns that run well and are easy to maintain. If you don’t have a solid code pattern, then your tool will just write bad code faster. When you look at the code output of my automation tool, you’ll see that the tool does all the data binding in .NET code, not in Extensible Application Markup Language (XAML). The reason I chose this approach is simple—separation of code and UI. Use of the separation of code and UI code pattern is a basic component design principle. Plus, the XAML for the form might become really complex if all the data binding is there, so I didn’t want to add to the complexity by mixing data binding code with it. For more information about automating processes, see the sidebar "Automating Development Can Lead to Project Success," InstantDoc ID 100363.
To download the code for the automation tool, click the 100362.zip hotlink at the top of this page. Open the WPFAutomaticDataBindingUI.sln solution in Visual Studio 2008 and compile it. Then click F5 to open a project to test the add-in. To run the tool, open the WPF form you want to perform data binding on and run the tool by selecting WPFAutomaticData BindingUI from the Tools menu in Visual Studio.
Figure 1 shows the UI after I ran the tool with a form open and then selected a property class (CustomersPropertyClass) to use as the data source for the form. The grid lists all the bindable controls found on the form. Each dropdown list to the right of a control contains the names of the properties from the properties class. To automatically wire up a control to a property, simply select the property to bind the control to. When you finish selecting properties, click Finish to close the form and write the code into the WPF forms code behind file.
I’ll highlight some key elements of the code in the tool for you here, but I encourage you to download and look through all the code. For more information about WPF data binding and Visual Studio 2008 add-in creation, see the Learning Path for this article online at InstantDoc ID 100362.
Building the Tool
Wiring up a UI is simple, after you’ve figured out the data source to which you want to bind the UI controls. For example, you might bind to a web service method result, a message from Windows Communication Foundation (WCF), a proxy class, or a SQL Server database. You have many options to choose from when deciding what to point your UI to. For the purposes of this article, I’ll have the tool bind to two sources of data: Property Class and DataTable.
Given these two sources, I can start to put together the code I need to retrieve the data. Listing 1 shows the data binding code I want to output when binding to a DataTable. The code calls the SelectAll method to return a data table of customers and then it sets the DataContext for the WPF window to that data table. The last line calls the SetupDataBinding function to perform the data binding magic.
The real work in setting up data binding comes when you must wire up the property of a control to a field in a data source that contains the data you want to display. For instance, the SetupDataBinding code shown in Listing 2 calls the SetBinding method of the TextBox controls to perform the binding operation, while the ComboBox1 has a slightly different syntax to do the same thing, as you can see in Listing 2.
When I figured out how the WPF data binding syntax worked, it was easy to automate. I chose not to output the form load code that gets the data from somewhere because that’s usually harder to do, but it’s simple code to write. Instead, I chose to automate the code output shown in Listing 2 because that varies greatly from form to form and also can be quite complex on a form with a lot of controls.
Creating the Tool
Now, I’ll show you how to generate the databinding code using my automation tool. Figure 2 shows the two projects that make up the tool as seen in Visual Studio 2008 Server Explorer. The WPFAutomaticDataBindingUI project is just the add-in shell and references the WPFAutomaticData BindingLibrary, which contains the form (DataBinding- MainForm), shown in Figure 1 and the code. If you want to use this tool outside of Visual Studio 2008, you can modify the code in WPFAutomaticDataBindingLibrary by pulling out the references to Visual Studio 2008 and having the library read the WPF code from disk instead of from Visual Studio 2008. When the DataBinding- MainForm (in the WPFAutomaticDataBindingLibrary project) loads, it calls the LoadControlsToGrid method which in turn calls GetControlDefinitions to load the controls from the WPF definition (XAML code). Since XAML is XML, it’s easy to parse. The GetControl Definitions function grabs the XMAL from Visual Studio 2008 with the following lines of code:
applicationObject.ExecuteCommand("View. ViewDesigner") txt = CType(applicationObject. ActiveDocument.Selection, EnvDTE. TextSelection) txt.SelectAll() xWPFElement = System.Xml.Linq.XElement. Parse(txt.Text)
This code makes sure the window is in ViewDesigner mode then takes the XAML and puts it in the txt variable, which is of type EnvDTE.TextSelection. Finally, it loads the xWPFElement (System.Xml.Linq.XElement) with the XAML. You can work with it using LINQ and anything else with Microsoft .NET Framework 3.5. The rest of the code in this method walks through each of the controls and loads certain properties of each control into a property class and then places that class into a generic list. This gives you a list of all the controls (along with the type of the control) that you can walk through with .NET to set up the data binding.
Continue to page 2
After the call to GetControlDefinitions, the Load- ControlsToGrid method has a generic list of all the XAML controls. The remaining code in this method walks through the items in the generic list and adds the valid ones to the DataGridView. The method determines which controls can be bound by calling the IsValidBindingType function, which returns True if the control’s type matches one in the Select statement of the IsValidBindingType function.
Now you have enough code to load all of the controls that can be bound that are in a XAML form into a DataGridView. You need to feed in the source of the data you want to display to allow the user to match up the data fields with the controls on the form. The data field to match to a control is selected by the user from the Data Source Type ComboBox. The list of items a user can choose in this combo box is set as either a DataTable (by allowing the user to select a SQL Server table) or Class (property class).
If users choose Class from the Data Source Type ComboBox, they will be prompted to select a property class. Then the tool will read the property class by calling the ProcessClassFileAnd- LoadProperties method in the DataBindingClass. This method simply reads the class file and finds all the property definitions and places them in a generic list.
If users select DataTable from the Data Source Type ComboBox, the tool displays other fields that point to the SQL Server table to bind to, as Figure 3 shows. Now you can enter a connection string and click the check mark to retrieve the list of tables from the database. Then you have just select a table from Tables ComboBox, and you can wire up the form.
The tool uses the MetaDataSQLServerSimple class to extract metadata from SQL Server, so it's easy to pull back information like table names and table fields.
Get Creative with the Tool
I hope you’ll enjoy working with this automation tool, but it’s just a starting point. For instance, you could add stored procedures to the tables so a developer could select a stored procedures output. Currently, the tool generates only Visual Basic .NET code, but you could modify it to generate C# code. Or, instead of wiring up WPF, try wiring up Silverlight 2.0. You could add many other features. If you want to change the tool, have at it.
Statement of Ownership
I certify that the statements made by me above are correct and complete: —Michele Crockett, Associate Publisher