MSDN Magazine - December 2007 - (Page 47) Figure 1 Population Mapping Application dency property is a property associated with a dependency object. Together, they form the core infrastructure behind many areas of WPF, including data binding, animation, and styles. Dependency objects are represented by instances of types derived from the DependencyObject class. Similarly, dependency properties are represented by instances of DependencyProperty that have been registered with the WPF property system. When used in an application’s data model, dependency properties vastly simplify code. They allow many tasks to be implemented directly rather than requiring controls to be explicitly manipulated by the programmer. Through the WPF declarative data binding and styling mechanisms, changes can then be automatically propagated to the UI without the need for custom logic. This makes the code underlying WPF user interfaces significantly easier to read, write, and maintain. It also promotes cleaner application architecture by encouraging better separation between individual layers. Finally, and most importantly, it lets you take advantage of tools such as Expression Blend™ to design user interfaces in a visual manner, concentrating on elements of style rather than on application logic. For a simple example of using dependency properties, see Figure 2. There I show a portion of the definition of the MapRegion class. MapRegion inherits from DependencyObject. Its primary purpose is to represent a geographical region within a map. It declares two dependency properties, RegionName and IsSelected. The dependency properties are declared by calling the shared Register method on the DependencyProperty class, providing the name of the property, its type, and the type of the class containing it (in this case MapRegion). The returned dependency properties are then assigned to public, shared, read-only fields declared on the class. This is done mainly to conform to WPF conventions, which expose the metadata for dependency properties as shared fields on the classes that define them. The dependency properties are then exposed to code via wrapper properties that invoke the GetValue and SetValue methods defined in the DependencyObject class, providing the appropriate DependencyProperty object as a parameter. This enables consumers of the MapRegion class to access dependency properties like any other normal instance property, while simultaneously taking advantage of the rich dependency property system in WPF. It’s worth mentioning that the actual property data is not stored directly as fields in the MapRegion class. Instead, WPF manages the storage for each dependency property attached to a dependency object, making them readily available through calls to SetValue and GetValue. You should also note that a dependency property can be registered with a dependency object only once. Attempting to register two dependency properties with the same name on the same type will result in an exception. In my example, I ensure that each dependency property is registered only once by declaring shared read-only fields with explicit initialization expressions that call DependencyProperty.Register. This causes the registration to be executed as part of the MapRegion class’s static constructor, which the common language runtime (CLR) ensures will be run exactly once (before any code referencing the MapRegion class executes). The XAML code shown in Figure 3 shows an example of how dependency properties can be used to automatically propagate changes from a domain model to an application’s user interface. It Figure 2 Snippet of the MapRegion Class Imports System.Collections.ObjectModel Public Class MapRegion Inherits DependencyObject Public Shared ReadOnly RegionNameProperty As DependencyProperty _ = DependencyProperty.Register(“RegionName”, GetType(String), _ GetType(MapRegion)) Public Shared ReadOnly IsSelectedProperty As DependencyProperty _ = DependencyProperty.Register(“IsSelected”, GetType(Boolean), _ GetType(MapRegion)) ‘ Public Property RegionName() As String Get Return CStr(GetValue(RegionNameProperty)) End Get Set(ByVal value As String) SetValue(RegionNameProperty, value) End Set End Property Public Property IsSelected() As Boolean Get Return CBool(GetValue(IsSelectedProperty)) End Get Set(ByVal value As Boolean) SetValue(IsSelectedProperty, value) End Set End Property december2007 47
For optimal viewing of this digital publication, please enable JavaScript and then refresh the page. If you would like to try to load the digital publication without using Flash Player detection, please click here.