IronPython – Data Binding and Data Templates – Part 1

Rob Oakes | January 6, 2009 1:12 am

Figure 1. The main Podcast list for Podcatcher. This is an example of WPF data binding where a data template and data trigger have been applied. The selected item shows the feed description in addition to the feed name, link and image.

One of the most important and fundamental purposes of computers is to manipulate information. This can range anywhere from simple storage and retrieval to complex applications, like automated detection of diseased heart tissue. However, automated manipulation of data is only of limited interest. At some point, data must interact with human beings in order to be interesting. Luckily, Windows Presentation Foundation (WPF) has an extremely powerful feature meant to facilitate man’s interaction with his data. This feature is called data binding. As described by Microsoft:

“Data binding is the process that establishes a connection between an application and the underlying logic. If the binding has the correct settings, when the data changes its value, the elements that are bound to the data reflect changes automatically.”

Data binding has appeared in many incarnations among the various Microsoft technologies. A version of it can be found in Windows Forms as well among the various voodoo cults of web programming. Since data binding has been around for a while, the version included in WPF is a very mature technology. Tens of thousands of developers have helped Microsoft work out the rough edges and it is possible to do some rather sophisticated things.

While data binding is capable of doing sophisticated things to complex sets of information, you won’t find much of that here. Rather, this article and the others in this series will focus on a very simple application: manipulating and displaying information from RSS feeds. After all, I am hardly an expert in either IronPython or WPF. Rather, I plan to stick to comfortable ground and I will be returning to my Podcast aggregator. Previously, I created a download manager to handle the work of retrieving files; now it’s time to start tackling another major module: the Library. In doing so, I will compose variations on a theme. I will show how WPF displays data and facilitates user interaction with that data. This article will introduce the features of the project and provide some background on data-binding. Later articles will look at code and how to add in bells and whistles.

The Project

With that introduction, let’s talk about some of my program’s needs. While the download manager of my Podcast aggregator is completed, a download manager without things to download is of little use. I, therefore, need a way to manage the podcasts I am currently subscribed to, delete podcasts which no longer interest me, and add additional podcasts. Much of the behind the scenes action will be provided by the Windows RSS platform but I still need to provide the user interface. This is where WPF comes in.

There are three major components to my planned library interface. First, I need a way to list the podcasts to which I am currently subscribed and view details about a selected podcast (Figure 1 provides an example of what this might look like). Next, I need to see individual episodes for that podcast and be able to interact with the items. For each item, I want to be able to download the feed enclosure, listen to it using my computer, send it to my mobile phone or handheld using Windows Media Player, or delete it from the list. Last, I want a way to add new Podcasts to my subscriptions. Since the Windows RSS platform is integrated with Internet Explorer that is one way which additional Podcasts can be added. However, this is not necessarily the best or most convenient way to add additional podcasts. Referring to other podcast aggregators, like iTunes, provides some additional ways content might be added.

A great strengths of iTunes is its integrated Podcast directory, which is maintained through the iTunes store. The podcast directory offers users a central place to browse and subscribe to content while at the same time providing a means to discover new and unappreciated podcasts. It might even be fair to say that the podcast directory is one of the most compelling reasons to use iTunes. After some thought, I decided that it would be very nice to have a similar feature within my own podcast aggregator.

Figure 2. iTunes Podcast Directory. The iTunes podcast directory, which is maintained by Apple, is a great way to discover new and unappreciated content.

It is very fortunate that a number of websites maintain directories similar to that in iTunes. While reading about the podcast support in one of my favorite Linux audio players, AmaroK, I stumbled upon a catalog maintained by DigitalPodcast.com. This particular directory is slightly different from others as they publish their entire catalog as an OPML feed. OPML is an XML format used for outlines and can be used to exchange a list of webfeeds between aggregators. To leave geek-speak behind for a minute, DigitalPodcast.com has made it ridiculously easy for anyone to add a Podcast directory to their program.

Figure 3. User Interface Mock-Up for Podcast Catalog in Podcatcher. The catalog is maintained by DigitalPodcast.com.

Data Binding Basics

Now that the project has been described, let’s review some of the fundamentals of data binding. These include how to create a binding and appropriately convert data when necessary in addition to defining some of the data binding vernacular. We’ll then look at how data can be presented in a uniform manner by the use of DataTemplates.

Data binding in WPF

Data binding in WPF can be used to connect a broad range of object properties to a very large variety of data sources. These include CLR objects, ADO.NET objects, objects associated with Web Services or Web properties as well as XML data. Objects which are bound to a given data set can be grouped, filtered or sorted. Any changes which occur to the underlying data are immediately reflected in the user interface.

Data binding works as bridge from the interface to the underlying data. In Microsoft’s language, the interface (or binding target) is also called a dependency object. The figure below (stolen from the data binding overview) shows how the data binding bridge works in practice. The binding target typically has a property which receives the data and the binding source typically has a property which supplies it. The link between the two can either be established in XAML or in code. Data can flow one-way (from the data source to the target or from the target to the source) or two ways where changes made to one are updated in the other instantly.

Should I data bind with XAML or Python?

In Windows Forms programming, much of the data binding occurs within the Visual Basic or C# code. WPF, however, is substantially different in that much of the syntax required for data binding appears alongside the XAML that defines the user interface. While it is possible to provide the syntax necessary for data binding from either XAML or code, it is easier to do some things from one location rather than the other. As my language of choice when working with WPF is Python, it should be mentioned that it is sometimes necessary to do things from code rather than from XAML. Defining how data should be presented in the XAML while managing the data source from the Python appears to work well.

Data Templates

WPF contains a convenient way to set up the presentation of data through the use of data templates. All but the most trivial WPF programming require a means to present data in a more powerful way than just binding one property on an object to one property on a data source. Often, a data source will contain many related values and those values should combine to form a cohesive visual representation. DataTemplates provide instructions to the binding target about how they should display the data provided by the source. Without a data template, the data may be presented as a list of custom clr objects, or the presentation might not appear as you would expect.

Data templates are typically applied to the ItemTemplate property of the binding target. Nearly all WPF controls have the ItemTemplate property. The ItemTemplate abstracts away the process of creating a proper container object. For example, if a data template is assigned to the ItemTemplate of a ListBox, the data binding classes will automatically generate a ListBoxItem. The DataTemplate could be applied to another control type, and the proper container would be generated for that object as well. Figure 1 in this article shows an example of a ListBox with a custom DataTemplate.

Conveniently, a DataTemplate can show mixed content including might include pictures, text or even animations. Further, through the use of styles and triggers, more than one DataTemplate can be used within the same object or a DataTemplate can be customized based on the content.

DataTemplates and Reusability

One of the greatest strengths of DataTemplates is their ability to be defined as a resource. This is typically done in the <Window.Resources> tag of the XAML file. An alternative is to declare the DataTemplate as part of the control which will use it. Consider the following examples, which create a very simple DataTemplate with only a single TextBlock. The first codeblock shows the template being declared inline and the second declares it as a resource.

<ListBox Width="400" margin="10" >
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path = FeedName}" />
        </DataTemplate>
    <ListBox.ItemTemplate>
</ListBox>
<Window.Resources>
    <DataTemplate x:Key = "Example1">
        <TextBlock Text = "{Binding Path = FeedName}" />
    <DataTemplate>
</Window.Resources>

There are substantial advantages to declaring a DataTemplate as a resource. The first is that it can be reused. It can be dynamically added to other controls that have a property which will accept a DataTemplate type. A second is that declarations within XAML are convenient. Such declarations are often shorter than their Python counterparts. An additional benefit is that declarations in XAML can act in a manner similar to a statically typed language without many of the drawbacks.

Declaring a DataTemplate as a Static Resrouce

As I mentioned above, it is possible to define data binding relationships completely from within the XAML markup. This ability is due to a feature of statically typed languages. When working with dynamic languages, we are then presented with somewhat of a conundrum. In many cases, data binding examples are performed completely within the XAML and this requires a statically typed language to function correctly. There is, however, a workaround for dynamic languages such as Python. DataTemplates can be declared as a Static Resource. When properly converted values are assigned, the data binding then just works. The code block below shows the main DataTemplate from Figure 1.

<Window>
    <Window.Resources>
        <DataTemplate x:Key="ShowFeed" >
            <Grid x:Name="LayoutRoot" Height="60" Margin="5">
                <Image HorizontalAlignment="Left" Margin="0,0,0,0"
                    Stretch="Fill" Width="60"
                    Source="{Binding Path=Image}"/>
                <TextBlock Margin="70,0,8,0" Text="{Binding Path=Name}"
                    FontSize="13" TextWrapping="Wrap" Height="35"
                    VerticalAlignment="Top" ScrollViewer.CanContentScroll="True"/>
                <TextBlock Margin="70,0,0,9" Text="{Binding Path=Link}"
                    FontSize="11" TextWrapping="Wrap" Height="16"
                    VerticalAlignment="Bottom"
                    ScrollViewer.CanContentScroll="True"/>
            </Grid>
        </DataTemplate>
    </Window.Resources> 

        <Grid>
            <ListBox x:Name = "listboxRssFeeds" Itemtemplate="{StaticResrouce ShowFeed}" />
        </Grid>
</Window>

 

The Python code includes a custom class that creates an object with Image, Name and Link properties. Once the values of the custom class are assigned to the DataSource property of the ListBox, the data is presented without further fuss. I will be returning to this example in depth during the next article in this series.

Data Triggers

Another powerful feature in DataTemplates is the ability to respond to the contextual details of the data. In Figure 1, the selected item shows the feed description in addition to the other information. This is accomplished by making use of a DataTrigger. DataTriggers are an important component of data binding and can be used to customize the appearance or response of a given object. They can include specific values within the data source or they can arise due to user interaction.

Using data triggers, it might be possible to bold the name of podcast feeds with new content or provide additional information about the selected feed. They are also highly flexible. Triggers can be defined within the DataTemplate itself or in the control where the DataTemplate will be applied. Given their importance, they will also feature prominently in Part 2 of this series.

Conclusion

Data binding and data templating are extremely powerful technologies that have been refined in WPF. Through the use of data binding, it is possible to present data in a highly attractive (and reusable manner). Further, it is possible to modify data presentation in response to its context and values. In this article, some of the important concepts and terms used in data binding and templating were reviewed. In Part 2 of this series, I will show how these concepts can be applied to a simple data source: a list of subscribed RSS feeds.

_____________________________________________________

Acknowledgements, References and Further Reading

The strategy and layout of this example has its roots firmly embedded in a DevHawk article on the same subject. It’s definitely worth having a look. The MSDN introductions to data binding and data templating give a good background of how these two technologies work. They also include an example that explores how these two technologies overlap.

The article “Data Binding in WPF” which was published in the December 2007 edition of MSDN magazine includes a great introduction to the core data binding concepts. Another article, “Customize Data Display with data Binding and WPF,” gives a good overview on how to separate data from its presentation.
_____________________________________________________

Similar Posts:

One Response to “IronPython – Data Binding and Data Templates – Part 1”

[...] and Photography « IronPython – Data Binding and Data Templates – Part 1 The Walmart Plague [...]