Over a million developers have joined DZone.

Custom Attached Properties in Silverlight

·

An attached property is a type of global property that is settable on any nested object. In Silverlight (and WPF), attached properties are usually defined as a specialized case of Dependency Properties, and like all dependency properties they are managed by the Silverlight property system. Attached properties differ in that they do not have the conventional "property wrapper".

Most commonly, attached properties are used in layout containers. Every control in XAML has its own set of internal properties. However, when this control is placed inside a container, it acquires additional features depending on the type of the container. For example, the Grid.Row property is created as an attached property because any control inside a Grid needs to specify the grid cell where it is positioned. For example:

<Grid x:Name="OuterGrid">
<TextBox x:Name="innerBox" Grid.Row="1"/>
</Grid>

Since the TextBox is nested inside the Grid, it gains the Row property which "attaches" to the TextBox instance. In essence, attached properties allow different child elements to specify values for a property defined in a parent element. Attached properties always use a two-part name of the form: AttachedPropertyProvider.PropertyName (OR simply DefiningType.PropertyName)

Defining a Custom Attached Property:

Creating an attached property is similar to how we create a custom dependency property with a few subtle differences. Since I seem to love widgets so much, I will continue to use a custom WidgetControl as an example. In one of my previous posts we saw how to create a custom dependency property for WidgetControl. In this post, we will see how to create the WidgetStateProperty as an attached property.

1. The first step is to define a static readonly DependencyProperty object that represents the property, and register this attached property with Silverlight. This is done via the Dependency.RegisterAttached() method.

public static readonly DependencyProperty WidgetStateProperty =
DependencyProperty.RegisterAttached(
"WidgetState",
typeof(Boolean),
typeof(WidgetControl),
new PropertyMetadata(false));

Notice that when we were creating custom dependency properties, we used the DependencyProperty.Register() method. The parameters for both these methods are exactly the same: the property name (WidgetState in this example), the data type used by the property (bool), the type that owns this property (WidgetControl), and a PropertyMetadata object that provides additional information, such as default values.

2. Our attached property provider must also provide static GetXXX() and SetXXX() methods, where XXX is the name of our property (WidgetState).

public static void SetWidgetState(UIElement element, Boolean value)
{
element.SetValue(WidgetControl.WidgetStateProperty, value);
}

public static Boolean GetWidgetState(UIElement element)
{
return (Boolean)element.GetValue(WidgetControl.WidgetStateProperty);
}

We now have a fully functioning attached property which can be set using the DefiningType.PropertyName syntax. The complete code for this WidgetControl is shown below:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Attached
{
public partial class WidgetControl : UserControl
{
public WidgetControl()
{
InitializeComponent();
}

public static readonly DependencyProperty WidgetStateProperty =
DependencyProperty.RegisterAttached(
"WidgetState",
typeof(Boolean),
typeof(WidgetControl),
new PropertyMetadata(false));

public static void SetWidgetState(UIElement element, Boolean value)
{
element.SetValue(WidgetControl.WidgetStateProperty, value);
}

public static Boolean GetWidgetState(UIElement element)
{
return (Boolean)element.GetValue(WidgetControl.WidgetStateProperty);
}
}
}

Here’s a very simple example where we use WidgetControl and its WidgetState property. The code is in XAML:

<UserControl x:Class="Attached.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Attached"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">

<Grid x:Name="LayoutRoot" Background="White">
<local:WidgetControl>
<TextBox x:Name="txtBox" local:WidgetControl.WidgetState="true">
</TextBox>
</local:WidgetControl>
</Grid>
</UserControl>

Finally, a couple of good resources that talk more about dependecy and attached properties are here and here.

 

Topics:

Published at DZone with permission of Umair Saeed. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}