XAML 101: Dependency Properties and Attached Properties

FacebookTwitterGoogle+Share

Source code for this sample on GitHub: https://github.com/billreiss/xamlnative/tree/master/Xaml101/003_Dependency_Attached_Properties

This is one of those topics where it’s pretty advanced, but it’s also so fundamental to the technology that it needs to be addressed. So what we will do is talk about these Properties as they are implemented by other controls, and later we will look at how we can create our own Properties. In the last post, we set the Text property of the TextBlock. This Text property, and pretty much every other property you set on a control is actually a Dependency Property. In C#, when you create a property it’s usually something like this:

        public string Text { get; set; }

In UWP and other XAML based technologies, properties that you need to be able to access in XAML are a bit more complex. There are things like animations, data binding, triggers, setters, and more and these require notifications when the value of a property is changed. Most properties on controls are implemented as Dependency Properties. These are properties that are registered, and their values are accessed via GetValue and SetValue methods. Generally they also have simple property wrappers around these methods so that you can access them as easily as any other property. A lot more about the details of how to implement these later.

The reason I think this is important to bring up now is that there is a type of Dependency Property that is called an Attached Property. Dependency Properties are declared on a class and then are attached to another class. Dependency Properties like the TextBlock.Text property are declared on the same class that they are attached to. If a Property is declared against one class, but is attached to a different class, then this is called an Attached Property. Yes I understand that this is a little confusing, and I think an example can help. Let’s start with the HelloXaml sample from the last post. In MainPage.xaml we had this:

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <TextBlock Text="Hello XAML!"/>
    </Grid>

Like I said earlier, the Text property of the TextBlock is a Dependency Property. The Background property of the Grid is too, we will talk about the strange syntax there soon. Dependency Properties in XAML can be set using XML attribute syntax (like Text and Background) but for more complex properties there is also an element syntax. Let’s consider defining two rows for our Grid control. There is a Dependency Property on Grid which is called RowDefinitions. This is how we can define two rows:

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <TextBlock Text="Hello XAML!"/>
    </Grid>

Now let’s put something in the second row. This is done using the Grid.Row Attached Property.

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <TextBlock Text="Hello XAML!"/>
        <TextBlock Grid.Row="1" Text="Hello Second Row!"/>
    </Grid>

The first row is row 0, so the second row is row 1. Notice the Grid.Row attached property on the second TextBlock. The Row attached property is declared on the Grid but is attached to the row, and that’s why when we use this attached property we need to say Grid.Row instead of just Row. You can actually put this prefix on any dependency property, but it’s not required. For example, instead of:

Text="Hello Second Row!"

We could say:

TextBlock.Text="Hello Second Row!"

Run this again and you will see something like this:

image

Notice how the rows are spaced and the two rows take up the same amount of space on the page. There are some other properties that can control this and in the next post we will see some of these.