A Property Defined by One Type, Set on Another
Grid.Row is the canonical example: Grid defines the property, but it is set on children like a TextBlock or Button that are not Grid instances themselves and know nothing about Grid internally. This works because Grid.Row is a special kind of dependency property — an attached property — registered with DependencyProperty.RegisterAttached, exposing static GetRow/SetRow accessor methods instead of an instance CLR wrapper, so any DependencyObject can carry the value even though the defining type never touches that object's class hierarchy.
Cricket analogy: It is like a stadium assigning a specific seat number to a ticket holder — the stadium (Grid) defines the seating system, but the seat number is attached to any spectator's ticket (any DependencyObject) regardless of which team they support.
Registering and Using an Attached Property
public static class WatermarkService
{
public static readonly DependencyProperty TextProperty =
DependencyProperty.RegisterAttached(
"Text",
typeof(string),
typeof(WatermarkService),
new FrameworkPropertyMetadata(string.Empty, OnTextChanged));
public static string GetText(DependencyObject obj) =>
(string)obj.GetValue(TextProperty);
public static void SetText(DependencyObject obj, string value) =>
obj.SetValue(TextProperty, value);
private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is TextBox tb)
AdornerLayer.GetAdornerLayer(tb)?.Add(new WatermarkAdorner(tb, (string)e.NewValue));
}
}
// XAML usage on any TextBox, without WatermarkService in its inheritance chain:
// <TextBox local:WatermarkService.Text="Search..."/>The static GetText/SetText method pair (matching the naming convention Get{Name}/Set{Name}) is what the XAML parser looks for when it encounters the attached property syntax owner.Property="value" on any element; without both methods present and correctly named, the property cannot be set from XAML even though the DependencyProperty itself is fully registered. Because SetValue works on any DependencyObject, attached properties are frequently used to add cross-cutting, reusable behavior (like the watermark above, or drag-and-drop helpers) to controls without subclassing them.
Cricket analogy: It is like a broadcaster's graphics package requiring both a 'tag player' and 'untag player' function pair before commentators can attach a live stat overlay to any player on screen — both halves must exist for the workflow to function.
Attached Properties vs. Regular Dependency Properties
A regular dependency property is registered with Register and is meaningful only in the context of instances of its owner type — Button.IsPressed only makes sense on a Button. An attached property is registered with RegisterAttached specifically because it is meant to be meaningful on arbitrary DependencyObject instances that have no relationship to the defining type; both still ultimately participate in the same GetValue/SetValue store and value-precedence system, so attached properties can be bound, styled, animated, and triggered exactly like regular dependency properties once set.
Cricket analogy: It is like the difference between a player's own batting average (meaningful only for that player) and a ground's altitude-adjustment tag (meaningful when attached to any match played there, regardless of team) — both are tracked in the same statistics database though.
Because attached properties can be set on any DependencyObject, it is easy to set one on a type where the owning class's change-handling logic does nothing meaningful — for example setting Grid.Row on an element that isn't a direct child of a Grid has no visible effect and produces no error. Always verify the attached property is set on an element whose parent actually reads it during layout.
- Attached properties are registered with DependencyProperty.RegisterAttached and can be set on any DependencyObject, not just instances of the defining type.
- The XAML parser requires matching static Get{Name}/Set{Name} accessor methods, not an instance CLR wrapper, to read and write the value.
- Grid.Row, Canvas.Left, and DockPanel.Dock are classic examples used by layout panels to position arbitrary child elements.
- Attached properties are commonly used to add reusable, cross-cutting behavior to existing controls without subclassing them.
- They participate in the same GetValue/SetValue store and value-precedence chain as regular dependency properties, so they support binding, styling, and animation.
- Setting an attached property on an element whose ancestor doesn't read it (e.g. Grid.Row outside a Grid) has no effect and raises no error.
- PropertyChangedCallback on an attached property is where reusable behavior logic typically lives, since there is no owning instance to react in its own code-behind.
Practice what you learned
1. What API is used to register an attached property, as opposed to a regular dependency property?
2. What must accompany an attached property's DependencyProperty field for XAML to be able to set it?
3. Why does setting Grid.Row on a Button that is not a direct child of a Grid have no visible effect?
4. Which of these is a typical use case for attached properties beyond built-in layout properties?
5. How do attached properties relate to the dependency property value-precedence chain?
Was this page helpful?
You May Also Like
Dependency Properties
Learn why WPF replaces plain CLR properties with DependencyProperty for UI elements, enabling data binding, styling, animation, and property value inheritance.
Data Binding Fundamentals
Learn how WPF connects UI elements to data sources through the Binding object, DataContext, and the {Binding} markup extension, eliminating manual UI-update code.
Binding Modes and Converters
Understand how BindingMode controls the direction of data flow between target and source, and how IValueConverter lets bindings transform data for display.
Related Reading
Related Study Notes in Microsoft Technologies
Browse all study notesWindows 10 / UWP Development Study Notes
.NET · 30 topics
Microsoft TechnologiesWindows Batch Scripting Study Notes
Batch · 30 topics
Microsoft TechnologiesMFC (Microsoft Foundation Classes) Study Notes
C++ · 30 topics
Microsoft TechnologiesSilverlight Study Notes
.NET · 30 topics
Microsoft TechnologiesXAML Study Notes
.NET · 30 topics
Microsoft TechnologiesMVVM Design Pattern Study Notes
.NET · 30 topics