
Property Functionality Provided by a Dependency Property
A dependency property provides functionality that extends the functionality of a property as opposed to a property that is backed by a field. Often, each such functionality represents or supports a specific feature of the overall WPF set of features:
Resources
A dependency property value can be set by referencing a resource. Resources are typically specified as child elements of a page root element, or of the application (these locations enable the most convenient access to the resource). The following example shows how to define a SolidColorBrush resource.
<DockPanel.Resources>
<SolidColorBrush x:Key="MyBrush" Color="Gold"/>
</DockPanel.Resources>
Once the resource is defined, you can reference the resource and use it to provide a property value:
<Button Background="{DynamicResource MyBrush}" Content="I am gold" />
This particular resource is referenced as a DynamicResource Markup Extension (in XAML, you can use either a static or dynamic resource reference). To use a dynamic resource reference, you must be setting to a dependency property, so it is specifically the dynamic resource reference usage that is enabled by the WPF property system. For more information, see Resources Overview.
Note: |
|---|
Resources are treated as a local value, which means that if you set another local value, you will eliminate the resource reference. For details, see
Dependency Property Value Precedence.
|
Data Binding
A dependency property can reference a value through data binding. Data binding works through a specific markup extension syntax in XAML, or the Binding object in code. With data binding, the final property value determination is deferred until run time, at which time the value is obtained from a data source.
The following example sets the Content property for a Button, using a binding in XAML. The binding uses an inherited data context and an XmlDataProvider data source (not shown). The binding itself specifies the desired source property by XPath within the data source.
<Button Content="{Binding XPath=Team/@TeamName}"/>
Note: |
|---|
Bindings are treated as a local value, which means that if you set another local value, you will eliminate the binding. For details, see
Dependency Property Value Precedence.
|
Dependency properties, or the DependencyObject class, do not natively support INotifyPropertyChanged for purposes of producing notifications of changes in DependencyObject source property value for data binding operations. For more information on how to create properties for use in data binding that can report changes to a data binding target, see Data Binding Overview.
Styles
Styles and templates are two of the chief motivating scenarios for using dependency properties. Styles are particularly useful for setting properties that define application user interface (UI). Styles are typically defined as resources in XAML. Styles interact with the property system because they typically contain "setters" for particular properties, as well as "triggers" that change a property value based on the real-time value for another property.
The following example creates a very simple style (which would be defined inside a Resources dictionary, not shown), then applies that style directly to the Style property for a Button. The setter within the style sets the Background property for a styled Button to green.
<Style x:Key="GreenButtonStyle">
<Setter Property="Control.Background" Value="Green"/>
</Style>
<Button Style="{StaticResource GreenButtonStyle}">I am green!</Button>
For more information, see Styling and Templating.
Animations
Dependency properties can be animated. When an animation is applied and is running, the animated value operates at a higher precedence than any value (such as a local value) that the property otherwise has.
The following example animates the Background on a Button property (technically, the Background is animated by using property element syntax to specify a blank SolidColorBrush as the Background, then the Color property of that SolidColorBrush is the property that is directly animated).
<Button>I am animated
<Button.Background>
<SolidColorBrush x:Name="AnimBrush"/>
</Button.Background>
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Loaded">
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetName="AnimBrush"
Storyboard.TargetProperty="(SolidColorBrush.Color)"
From="Red" To="Green" Duration="0:0:5"
AutoReverse="True" RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
For more information on animating properties, see Animation Overview and Storyboards Overview.
Metadata Overrides
You can change certain behaviors of a dependency property by overriding the metadata for that property when you derive from the class that originally registers the dependency property. Overriding metadata relies on the DependencyProperty identifier. Overriding metadata does not require re-implementing the property. The metadata change is handled natively by the property system; each class potentially holds individual metadata for all properties that are inherited from base classes, on a per-type basis.
The following example overrides metadata for a dependency property DefaultStyleKey. Overriding this particular dependency property metadata is part of an implementation pattern that creates controls that can use default styles from themes.
public class SpinnerControl : ItemsControl
{
static SpinnerControl()
{
DefaultStyleKeyProperty.OverrideMetadata(
typeof(SpinnerControl),
new FrameworkPropertyMetadata(typeof(SpinnerControl))
);
}
}
For more information about overriding or obtaining property metadata, see Dependency Property Metadata.
Property Value Inheritance
An element can inherit the value of a dependency property from its parent in the tree.
Note: |
|---|
Property value inheritance behavior is not globally enabled for all dependency properties, because the calculation time for inheritance does have some performance impact. Property value inheritance is typically only enabled for properties where a particular scenario suggests that property value inheritance is appropriate. You can determine whether a dependency property inherits by looking at the Dependency Property Information section for that dependency property in the SDK reference.
|
The following example shows a binding, and sets the DataContext property that specifies the source of the binding, which was not shown in the earlier binding example. The value of the DataContext property inherits by property value inheritance to all child objects in the logical tree. Any subsequent bindings in child objects do not need to specify the source, they can use the inherited value from DataContext in the parent StackPanel object. (Alternatively, a child object could instead choose to directly specify its own DataContext or a Source in the Binding, and to deliberately not use the inherited value for data context of its bindings.)
<StackPanel Canvas.Top="50" DataContext="{Binding Source={StaticResource XmlTeamsSource}}">
<Button Content="{Binding XPath=Team/@TeamName}"/>
</StackPanel>
For more information, see Property Value Inheritance.
WPF Designer Integration
A custom control with properties that are implemented as dependency properties will receive appropriate Windows Presentation Foundation (WPF) Designer for Visual Studio support. One example is the ability to edit direct and attached dependency properties with the Properties window. For more information, see Control Authoring Overview.