Since the early days of the personal computer revolution, the gap between what can be visualized in the imagination and what can be visually rendered by the typical application developer has been wide. The introduction of Windows Presentation Foundation (WPF) has greatly narrowed that gap. A rich visual experience is now within reach of any business application developer—no DirectX or DirectShow experience is needed.
Although the gap has narrowed, a learning curve still remains. The Windows SDK is flush with hundreds of samples covering every aspect of WPF from basic to advanced situations; it's impractical to cover every scenario, especially more specialized edge cases. One of the more useful edge case scenarios is the dynamic DataTemplate. This article will show you how to dynamically build a DataTemplate and use the DataTemplate with a WPF control.
WPF and XAML
If WPF, Extensible Application Markup Language (XAML), DataTemplates, and Bindings are new terms to you, read on; otherwise, you can skip the next two sections.
A complete introduction to WPF development is beyond the scope of this article. So, this introduction will be confined to the DataTemplate and related concepts.
WPF is a data visualization engine built on top of familiar Microsoft technologies such as DirectX and DirectShow. As with other parts of the .NET framework, WPF is designed to make low-level libraries built into the Windows operating system more accessible to a developer. WPF richly renders all types of data, including media. The WPF development experience combines the best of what you may have seen in web development, embodied in XAML, with what you've seen in traditional Forms development, including drag-and-drop controls with properties.
In addition, WPF offers better and more consistent decoupling between the user interface and the business logic. So, for example, you can truly separate the user interface from the rest of the application.
Although WPF applications are bound to the Desktop, Silverlight hosts a subset of WPF in the browser for Rich Internet Applications.
|You can find a more complete overview to WPF in the WPF documentation.|
WPF allows you to code a complete application in XAML or purely in, for example, C#. Most WPF applications will combine the two coding methods, often expressing the more static parts of the application in XAML and the more dynamic pieces in C# or VB.NET.
DataTemplates and Bindings
Two of the core parts of WPF are Dependency Properties and Binding classes (Bindings). Dependency Properties and Bindings work together to move data out of business logic and into the user interface to be rendered by WPF.
Many of the WPF controls have Dependency Properties that allow a developer to create interdependencies between controls and underlying data. So, for example, a developer can express a relationship between a button's color and the background color of the window it sits on. Once the relationship is established, runtime changes to the background of the Window with cascade to the button. The power of Dependency Properties is that you establish the relationship and WPF takes care of the rest.
Dependency Property relationships are expressed in a Binding. A Binding's Path expresses where the Binding goes to get data. There are a myriad of ways to express and extend Bindings. Like Dependency Properties, the power of Bindings is that once you define the Binding in XAML or code, WPF handles the rest. The relationships between Dependency Properties and Bindings is depicted in Figure 1.
Figure 1: Relationship between Dependency Properties and Bindings
DataTemplates allow a developer to customize the "look" and "feel" of a control; this allows a developer to, for example, place controls within other controls. As I'll show you later, a DataTemplate is assigned to a DependencyProperty and Bindings within the DataTemplate dictate where to go in the source object for data.
With the WPF introduction complete, I'm moving to some practical application of the features I've covered. First, I'll explain how the sample works and then I'll highlight the key parts of the sample code.
The sample is straightforward. In the top of the window a user enters a SELECT statement for a table in the AdventureWorks database and then presses the button to generate a columned list of all the data in the select statement.
The code executes as follows:
- The application generates a DataSet.
- Then, it generates a DataTemplate based on the DataSet.
- Next, it programmatically applies the DataTemplate to the listview control on the screen.
- Finally, it loads the data into the listview.
Double-clicking on any row in the list will load the textbox at the bottom of the screen with the window.