
hen Microsoft's developers invented WPF, they made some fundamental changes in the way things work. Two of those changes redefine the fundamental nature of properties and events.
To replace the existing properties and events that we all know and love, WPF introduced dependency properties and routed events. This article provides an introduction to dependency properties and routed events, and explains how you can set properties and intercept events in XAML.
But first things first. Before you can set a dependency property's value, you need to know what one is.
Dependency Properties
A
dependency property is a special kind of property that is registered with the WPF property system. Dependency properties support features that normal properties do not, such as default values, inheritance, WPF-style data binding, and property change notification.
For example, the
InheritedProperties sample program shown in
Figure 1 (available in the
downloadable code in both C# and Visual Basic versions) uses the following code to display a StackPanel that holds three Labels, a ListBox, and a Button:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="InheritedProperties.Window1"
x:Name="Window"
Title="InheritedProperties"
Width="317" Height="329"
FontFamily="MS Sans Serif" FontSize="18" FontWeight="Bold"
Background="Orange">
<StackPanel Margin="5">
<Label Margin="5" Content="Inherited Font"/>
<Label Margin="5" Content="Overridden Font"
FontFamily="Mistral" FontSize="35"/>
<Label Margin="5" Content="Overridden Background"
Background="Yellow"/>
<ListBox Margin="5">
<ListBoxItem Content="Item 1"/>
<ListBoxItem Content="Item 2"/>
<ListBoxItem Content="Overridden
Background" Background="LightGreen"/>
</ListBox>
<Button Width="200" Height="50">
<Grid>
<Label Margin="5" Content="Label In Button"/>
</Grid>
</Button>
</StackPanel>
</Window>
 | |
Figure 1. Contested Inheritance: A control generally inherits properties from its container, although some (such as ListBox and Button) do not inherit properties such as Background. |
The Window in
Figure 1 defines font properties and a background color (orange). The StackPanel and the first Label control ("Inherited Font") do not define any font or background properties so they inherit both from their container—the Window. The second Label ("Overridden Font") does set
FontFamily and
FontSize properties, so these override the inherited values, but it keeps the inherited background color.
The third label in
Figure 1 ("Overridden Background") does the opposite; it overrides the inherited
Background property , but keeps the inherited font properties.
Some controls don't follow the normal inheritance mechanism, however. The ListBox control in
Figure 1 does not honor its parent's
Background property setting, although it does inherit font properties.
Author's Note: I think the ListBox doesn't inherit the Background property because it gives selected items a special highlighted background that might not look good with an inherited Background. However, you can still alter the default ListBox background color by setting its Background property explicitly so the problem is still possible; you just have to take an extra step to get into trouble. |
In
Figure 1, The ListBox's first two items inherit font and background properties from the ListBox that contains them, although the third item overrides its background value.
Like the ListBox, the Button does not inherit its
Background setting from its parent, although it does inherit font properties.
Dependency properties provide for considerably more complex inheritance than this example demonstrates. For example, if a control has a
Style that sets its
Background value, the Style background value takes precedence over an inherited value, but can be superseded by any value set explicitly on the control.
All this inheritance, with exceptions and style overrides, is provided by dependency properties. You'll see more about dependency properties in future articles, particularly about using them for data binding and change notification. For now, you need to know how to set simple and complex property values in program code or XAML.