Timo Korinth

2 Meter, 2 Mark

How to make attached properties Blendable

| 0 comments

As a WPF or Silverlight developer you probably already used attached properties or even wrote your own. I don’t want to go into detail on creating your own attached properties, rather than making them Blendable. By that I generally mean the designer support, whether it’s the Visual Studio Designer or Expression Blend. The goal is the visualization of your own attached properties, similar to the following screenshot:

gridattachedpropertiesblend

This figure shows the most frequently used attached properties of the class Grid. These properties have a meaningful name (eg “RowSpan” and not “Grid.RowSpan”), are assigned to a category (“Layout”) and are showing a tooltip with a small description. in addition to that, Blend only shows attached properties on elements that are located directly within a grid, because they only make sense in that place (which does not mean, that they can not be defined on all other elements). All of these characteristics we want to define for our own attached properties.

The easiest and fastest way to define your own attached property, is to use the Visual Studio code snippet “propa”. Thus the basic structure of an attached property is applied (very similar to a dependency property). Once you have defined your attached property in a class, it can be used on any element. Is the attached property defined on a control, it can be useful to do something, after the value has changed (such as an update of the view). To achieve this, it’s necessary to access the actual instance of the surrounding control, inside of the static event handler. Unlike in a dependency property, the sender is not the control, in which the attached property is defined, but the initiating control. Nevertheless, to get access to the surrounded Control, you can use a trick:

private static void PositionChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
    var element = sender as UIElement;
    var parentControl = VisualTreeHelper.GetParent(element) as Grid;
    if (element != null)
    {
        ...
    }
}

So it’s possible to access the targeted control, even from the static method. The example code, of course,  only works if the control is the direct parent.

But the newly created attached property isn’t displayed in Blend right away. To achieve this, there are several attributes. One of them is [AttachedPropertyBrowsableForChildrenAttribute (IncludeDescendants = true)]. This attribute tells the decorated attached property to be displayed for all the children of the surrounding control. Is the attached property defined in its own custom control, Blend will automatically offer the property for all the children of this control (for all children if IncludeDescendants = true, or only for direct children if IncludeDescendants = false).

Additionally, you can define a more meaningful, shorter name, a category and a description text , by using the attributes [Category (“…”)], [Description (“…”)] and [DisplayName (“…”)]. IMPORTANT: For all attributes on attached properties, it is essential to be declared on the get-method!

[AttachedPropertyBrowsableForChildrenAttribute(IncludeDescendants = true)]
[Category("Layout"), Description("Sets the Column span."), DisplayName("ColumnSpan")]
public static int GetColumnSpan(DependencyObject obj)
{
    return (int)obj.GetValue(ColumnSpanProperty);
}

public static void SetColumnSpan(DependencyObject obj, int value)
{
    obj.SetValue(ColumnSpanProperty, value);
}

public static readonly DependencyProperty ColumnSpanProperty = 
    DependencyProperty.RegisterAttached("ColumnSpan", typeof(int), typeof(ExtDetailsViewAreaContainer), 
    new UIPropertyMetadata(0, PositionChanged));

Accordingly decorated attached properties are now visualized correctly:

eigeneattachedpropertiesblend

There are a few other attributes in this context. The following links will provide you with more information about it:

Attached Propertis Overview (MSDN)

Leave a Reply