I'm a bit mystified as to how Attached Properties actually convey their values to either parent or child elements. TextElement.FontFamily
causes child elements to inherit the value assigned to that property (a seemingly downstream operation, parent to child). Grid.Column
causes a parent item to display that child in a particular position (a seemingly upstream operation, child to parent). How do Attached Property values know to either flow up or down? Is my conception of this incorrect, or is there a piece missing that will put all of this into perspective?
<StackPanel TextElement.FontFamily="Wingdings"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Button Grid.Column="1" Content="My Button"/> </Grid> </StackPanel>
An attached property is a Extensible Application Markup Language (XAML) concept. Attached properties enable extra property/value pairs to be set on any XAML element that derives from DependencyObject, even though the element doesn't define those extra properties in its object model.
The purpose of dependency properties is to provide a way to compute the value of a property based on the value of other inputs, such as: System properties, such as themes and user preference. Just-in-time property determination mechanisms, such as data binding and animations/storyboards.
Using the readonly keyword has at least three effects: it informs readers of the code that the value will not change. it prevents the author from accidentally changing the value. it assists the compiler, which benefits from knowing when things will not change.
There are two concepts here: dependency properties and attached dependency properties. "Attached Properties" are dependency properties, and as such support dependency property value inheritance.
About basic dependency properties, a very rough statement would be that they basically inherit their values from parent elements in the wpf (logical/visual) tree. A dependency property (attached or not) inherits its value "downwards" if its metadata is set with the FrameworkPropertyMetadataOptions.Inherit flag, and in many cases this is so.
Attached properties are properties which can be set on any wpf object (basically, at least a DependencyObject) via the DependencyObject.SetValue method. The purpose for this mechanism is to "attach" to other objects information needed by parent objects, not the child objects themselves. For example, the Grid.Row is an attached property required by the Grid to place items within its render area.
Dependency properties are inherited "downwards" automatically by the wpf object system.
Attached properties are examined "upwards" explicitly, in the code of specific objects. In the case of Grid, upon determining where to place its items, it checks for the value of Grid.Row and Grid.Column attached properties on each contained item.
It is also often the technique to create custom attached properties which modify in some way the objects they are attached to (for example, the Drag'n'Drop functionality via attached properties).
As an additional note, a good example of an inheriting attached property is TextElement.FontFamily. Grid.Row and Grid.Column properties do not have the Inherits flag set.
TextElement.FontFamily, from Reflector:
FontFamilyProperty = DependencyProperty.RegisterAttached("FontFamily", typeof(FontFamily), typeof(TextElement), new FrameworkPropertyMetadata(SystemFonts.MessageFontFamily, FrameworkPropertyMetadataOptions.Inherits | FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure), new ValidateValueCallback(TextElement.IsValidFontFamily));
Grid.Row, from Reflector:
RowProperty = DependencyProperty.RegisterAttached("Row", typeof(int), typeof(Grid), new FrameworkPropertyMetadata(0, new PropertyChangedCallback(Grid.OnCellAttachedPropertyChanged)), new ValidateValueCallback(Grid.IsIntValueNotNegative));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With