Dependency properties in Silverlight

Published: 8/23/2010
By: Manning Publications

This article is taken from the book Silverlight in Action, Revised Edition. The author discusses dependency properties, which can be data bound, the target of an animation, or set by a style. He also shows how an object can be bound to elements within a DependencyObject.

Contents [hide]



About the book

This article is taken from the book Silverlight in Action, Revised Edition. The author discusses dependency properties, which can be data bound, the target of an animation, or set by a style. He also shows how an object can be bound to elements within a DependencyObject.


Written by: Pete Brown
Pages: 425
Publisher: Manning
ISBN-10: 9781935182375
Get 30% discount

DotNetSlacker readers can get 30% off the full print book or ebook at www.manning.com using the promo code dns30 at checkout.

There are two ways to reference properties in XAML: in line with the element, as you would any XML attribute, and as a nested subelement. The one you choose depends on what you need to represent. Simple values are typically represented with in-line properties, whereas complex values are typically represented with element properties.

The use of an in-line property requires a type converter that will convert the string representation, for example the "Black" in Background="Black" into the correct underlying .NET type, in this case a SolidColorBrush. The example in listing 1 shows a built-in type converter in use to convert the string “Black” for the in-line property Background.

Listing 1: Specifying a property value in line, using an XML attribute

#1 In-line property

Another way to specify properties is to use the expanded property element syntax. While this can generally be used for any property, it is typically required only when you need to specify something more complex than the in-line syntax will easily allow. The syntax for element properties is value, as seen in listing 2.

Listing 2: Specifying a property value using property element syntax

#1 Property element syntax

The use of the string to invoke the type converter is, in its end result, identical to using <SolidColorBrush Color="Black" /> in place of "Black". While these examples are rarely seen in practice, the more complex example of setting the background to a LinearGradientBrush is quite common, so we'll cover that next. Rather than have the value represented as a simple string such as "Black", the value can be an element containing a complex set of elements and properties such as the <LinearGradientBrush> seen in listing 3.

Listing 3: A more complex example of the property element syntax

#1 Background property
#2 A type of brush
#3 More property elements

Now that we know how to specify properties in markup, let's dive a bit deeper into how dependency properties work.

Dependency properties defined

Dependency properties are part of the property system introduced with WPF and used in Silverlight. In markup and in consuming code, they are indistinguishable from standard .NET CLR properties, except that they can be data bound, the target of an animation, or set by a style.

A property cannot be the target of an animation or obtain its value through binding unless it is a dependency property. The Binding class is used to define a connection between a CLR object and a UI component. This connection is defined by three essential elements: the source of the data (the CLR object), the binding mode, and the target for the data (the dependency property). These three items are part of a conceptual model that explains binding. This model is shown in figure 1.

Figure 1: A conceptual view of data binding. The source owns the data and the target operates on the data (for example, displays and edits).

To have dependency properties in a class, the class must derive from DependencyObject or one of its subclasses. Typically, you will do this only for visuals and other elements that you'll use within XAML and not in classes defined outside of the user interface.

The target element of a binding will always derive from the DependencyObject class. Virtually every visual element in Silverlight can be a target because the DependencyObject class exposes a method called SetBinding. This method associates a target property, which must be a dependency property, with a Binding instance. After this method is called, the source will be bound to the target.

In regular .NET code, when you create a property, you typically back it by a private field in the containing class. The storage of a dependency property differs in that the location of its backing value depends upon its current state. The way that location is determined is called value precedence.

Value precedence

Dependency properties obtain their value from a variety of inputs. What follows is the order the Silverlight property system uses when assigning the runtime values of dependency properties, with the highest precedence listed first:

The strict precedence rules allow you to count on behaviors within Silverlight, such as being able to override elements of a style by setting them as local values from within the element itself. In listing 4, the foreground of the button will be red, as set in the local value, and not black, as set in the style. The local value has a higher precedence than the applied style.

Listing 4: Dependency property precedence rules in practice

The Style tag in UserControl.Resources is a reusable asset that sets some key properties for our button. Next we’ll show you how to bind multiple properties of an object to a UI, which is done using the DataContext property.

Binding to an object

The DataContext property allows you to share a data source throughout a DependencyObject. This data source can be used by all the child elements of a DependencyObject that define a Binding. Binding uses the most immediate ancestor’s DataContext unless another data source is set to it. If another data source is set, that source is used for the Binding. Either way, by relying on the DataContext of an ancestor, you can easily bind several properties of an object to a UI. This approach is shown in listing 5.

Listing 5: Binding an Emoticon object to a Grid

#1 LayoutRoot
#2 Binding statements
#3 LayoutRoot's DataContext

Listing 5 shows how an object can be bound to elements within a DependencyObject. The TextBox and Image elements in this example show their intent to bind to two different properties of an object. These elements don’t have their DataContext property set in the code behind, so the elements look to their immediate parent, myGrid, and try to use its DataContext. This DataContext has been set in the code behind. The object assigned to the DataContext serves as the data source for the Grid and its children. If the DataContext of the Grid hadn’t been set, the elements would have continued up the tree and checked the UserControl element’s DataContext. If that DataContext were set, it would have been used. Either way, this example shows how much more succinct and maintainable the DataContext approach can be.

Summary

Silverlight development is all about code + markup. To make the most of the platform, you'll want to learn how to leverage the capabilities that XAML provides, while keeping a balance between what you write in code and what you put in the markup. You’ve learned about dependency properties, which can be data bound, the target of an animation, or set by a style.

You’ve taken a little peek into the power of the Binding object, which gives you the flexibility to bind to individual entities, to a collection of entities, to indexed entries in a collection, and even to other UI elements. If you need to massage the data either coming or going, Silverlight provides a way for you to create your own value converters to do that. If you simply need to format the display, Silverlight provides a way for that too.

Get 30% discount

DotNetSlacker readers can get 30% off the full print book or ebook at www.manning.com using the promo code dns30 at checkout.

Please visit the link at the below url for any additional user comments.

Original Url: http://dotnetslackers.com/articles/silverlight/Dependency-properties-in-Silverlight.aspx