Meet DependencyObject and DependencyProperty, the .NET Data-Binding Boosters

With the introduction of the .NET 3.0 Framework, Microsoft made the DependencyObject and the DependencyProperty fundamental concepts, placing them at the forefront of development. Using these two items in conjunction enables .NET developers to expose some of the powerful features of the Windows Presentation Foundation (WPF).

In the meantime, data binding has proven to be a valuable construct within the development world. This article introduces data binding and explains how it can be effectively implemented using the DependencyObject/DependencyProperty within the WPF.

What Is Data Binding?

As the name of the functionality implies, data binding is essentially a way to bind to data. Basically, you can view it as a way to create a link or a connection between a source item and a target item. The source item owns the desired information and the target item is dependent upon this information.

There are two fundamental types of data binding in Windows:

  1. OneWay mode binding via System.Windows.BindingMode.OneWay, in which one item listens to another, but the second item does not listen to first.
  2. TwoWay mode binding via System.Windows.BindingMode.TwoWay, in which the two items essentially are listening to each other.

Figure 1 illustrates the first type of data binding. The illustration may be unfair to principals, but the general idea is there. This approach automatically transfers the value of the source property to the target property. This means, if the source property changes, the target property changes. However, if the target property changes, the source property does not change.

Figure 1. Data Binding in OneWay Mode

Figure 2 illustrates the second type of data binding. Changes from one property are automatically propagated to the other property. This means if the source property changes, the target item changes. Conversely, if the target item changes, the source item changes.

Figure 2. Data Binding in TwoWay Mode

To understand the power of data binding, consider a program guide system for a television receiver. Imagine if viewers had to select "get the latest television guide" and wait for the program data to be retrieved every time they turned on their televisions? Obviously, they should not have to do that. Program guide systems automatically provide viewers with up-to-the-minute program data.

In much the same way, data binding provides a way for developers to get the most up-to-date program data automatically. Without data binding, developers essentially would have to click a "get the latest program data" button to perform a data-retrieval task.

Why Should I Care?

Utilizing the DependencyObject and DependencyProperty provides a way to retrieve values from other items dynamically at runtime. In an event-based model, a developer would have to write code to handle an event and define what should happen with the event. With the DependencyProperty, a developer can essentially bind a property to another property and the value is set dynamically at runtime as the value changes.

For illustration, picture a typical media player with a volume-control dial. Turning the dial either increases or decreases the volume. Traditionally, a developer would have to write code to set the volume as the dial turns. However, with the DependencyObject/DependencyProperty, the developer essentially can bind the value of the volume to the dial and then the volume updates automatically.

From a technical point of view, utilizing the DependencyObject and DependencyProperty objects has a number of benefits. Chiefly, using the DependencyProperty object exposes some powerful features of WPF, including but not limited to the following:

  • Animations
  • Data binding, which you now know all about
  • Metadata overrides, which let you alter behaviors derived from metadata
  • Property value inheritance, which enables you to use the value of a parent object

How Do I Do It?

To demonstrate the usefulness of data binding, consider a desired solution involving fantasy football. An important feature of fantasy football is the ability to view player profiles. The example in this article demonstrates how to provide this feature with data binding.

Before actually binding to a source, the source must be defined. For the purpose of this example, the source will be defined using the DependencyObject/DependencyProperty approach. However, data source objects do not need to be DependencyObject instances. In fact, WPF is very flexible and supports data-binding in several other forms, including:

  • Data exposed through ADO.NET
  • Traditional CLR objects
  • XML data

The following code defines a typical object with three properties, representing a football player:

  • FirstName: The player's first name
  • LastName: The player's last name
  • Position: The player's position on the team (in other words, "QB", "WR", "TE", and so forth)
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;

namespace Source_Code
{
   public class Player : DependencyObject
   {
      public static DependencyProperty FirstNameProperty =
         DependencyProperty.Register("FirstName", typeof(string),
                                     typeof(Player));
      public string FirstName
      {
         get { return (string)GetValue(FirstNameProperty); }
         set { SetValue(FirstNameProperty, value); }
      }

      public static DependencyProperty LastNameProperty =
         DependencyProperty.Register("LastName", typeof(string),
                                     typeof(Player));
      public string LastName
      {
         get { return (string)(GetValue(LastNameProperty)); }
         set { SetValue(LastNameProperty, value); }
      }

      public static DependencyProperty PositionProperty =
         DependencyProperty.Register("Position", typeof(string),
                                     typeof(Player));
      public string Position
      {
         get { return (string)(GetValue(PositionProperty)); }
         set { SetValue(PositionProperty, value); }
      }
   }
}

Meet DependencyObject and DependencyProperty, the .NET Data-Binding Boosters

The code sample displays something slightly different from a traditional .NET object. First, the Player object derives from the DependencyObject. This is necessary to implement DependencyProperty properties. Declaring an object as a DependencyObject informs the system that the object wants to utilize the built-in features defined earlier.

Second, several of the properties are defined as DependencyProperty items. When providing a DependencyProperty to back a property, the property is exposed to the dependency system, which automatically gives the powerful features defined previously. You can utilize both traditional properties and DependencyProperty items within a DependencyObject. However, only the DependencyProperty items will gain the pre-defined built-in features.

After defining the source (the Player object), the target item can bind, or interact, with the source. At this point, the target has not been defined. This example creates a simple player profile page, which will display a player's first name, last name, and position. Here is the XAML code for the window that will display this information:

<Window x:Class="Source_Code.Profile"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:AppCode="clr-namespace:Source_Code"
   Title="Player Profile" Height="300" Width="300"
   >

   <StackPanel Name="ProfileStackPanel" Orientation="Horizontal">
   <TextBlock Name="LastNameTextBlock" />
   <TextBlock Text=", " />
   <TextBlock Name="FirstNameTextBlock" />
   <TextBlock Text=" - " />
   <TextBlock Name="PositionTextBlock" />
   </StackPanel>
</Window>

Placing this code into XAMLPad simply displays a ", b



Downloads

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • On-demand Event Event Date: September 10, 2014 Modern mobile applications connect systems-of-engagement (mobile apps) with systems-of-record (traditional IT) to deliver new and innovative business value. But the lifecycle for development of mobile apps is also new and different. Emerging trends in mobile development call for faster delivery of incremental features, coupled with feedback from the users of the app "in the wild." This loop of continuous delivery and continuous feedback is how the best mobile …

  • QA teams don't have time to test everything yet they can't afford to ship buggy code. Learn how Coverity can help organizations shrink their testing cycles and reduce regression risk by focusing their manual and automated testing based on the impact of change.

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds