Wednesday, July 6, 2011

Attached Properties in WPF


Attached properties are special type of dependency properties. The special thing about this property is that they can be set from any object of class other than they are defined. The object on which they are used is called as target object. The common attached properties are Grid.Row, Grid.Column, Canvas.Top, Canvas.Left, DockPanel.Dock, TextElement.FontSize, TextElement.FontWeight etc.

<Grid TextElement.FontStyle="Italic" TextElement.FontWeight="Bold">
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="0.8*" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Label Grid.Row="0" Grid.Column="0"
           Content="Enter value:" VerticalAlignment="Center"
           Margin="5"  />
    <TextBox Grid.Row="0" Grid.Column="1"
             Name="MyText" Height="25" Margin="5" />
    <Button Grid.Row="1" Grid.ColumnSpan="2"
            Content="Save" Height="30" Width="100" />
</Grid>

In above XAML code you can see the use of attached properties like TextElement.FontStyle, TextElement.FontWeight, Grid.Row, Grid.Column etc. You also noticed that these properties are setting from other instances like TextElement.FontStyle attached property value set from Grid similar Grid.Row value set from Label and TextBox etc.

You can also create your own Attached Dependency Property.  

<Window x:Class="WpfApplication1.AttachedPropertyDemo"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1"
        Title="AttachedPropertyDemo" Height="200" Width="250">
    <Window.Resources>
        <local:AttachedPropertySample local:AttachedPropertySample.TextAttachedProperty="Attached Property Test" x:Key="TestAttachedProperty" />
    </Window.Resources>
<Grid>
</Grid>
</Window>

public class AttachedPropertySample : DependencyObject
{
    //Register Attached Property
    public static DependencyProperty MyAttachedProperty =
        DependencyProperty.RegisterAttached("TextAttachedProperty",
        typeof(string), typeof(AttachedPropertySample),
        new PropertyMetadata("Test",
        new PropertyChangedCallback(OnMyAttachedPropertyChanged)));

    //Get Attached Property Value
    public static string GetTextAttachedProperty(
                         AttachedPropertySample attachedSample)
    {
        return (string)attachedSample.GetValue(MyAttachedProperty);
    }

    //Set Attached Property Value
    public static void SetTextAttachedProperty(
                  AttachedPropertySample attachedSample, string value)
    {
        attachedSample.SetValue(MyAttachedProperty, value);
    }
    //On Value change of Attached Property
    public static void OnMyAttachedPropertyChanged(
           DependencyObject dObject, DependencyPropertyChangedEventArgs e)
    {
        MessageBox.Show(e.NewValue.ToString());
    }
}

You can also create Attached ReadOnly Dependency Property for that you need to register dependency property using DependencyProperty.RegisterAttachedReadOnly. This readonly attached properties can be created similar to readonly dependency properties. You can go through my post related dependency property here and checkout how to create readonly dependency properties.


You might also like
Dependency Property
WPF Class Hierarchy
XAML Overview

1 comment: