(X) Hide this
    • Login
    • Join
      • Say No Bots Generate New Image
        By clicking 'Register' you accept the terms of use .

Attached Properties in Silverlight

(9 votes)
Ilia Iordanov
>
Ilia Iordanov
Joined Oct 25, 2007
Articles:   12
Comments:   89
More Articles
9 comments   /   posted on Jun 03, 2008
Categories:   Patterns and Practices , General
This article is compatible with the latest version of Silverlight.


1.       Introduction

An attached property is a new concept that is defined by Extensible Application Markup Language (XAML). The attached properties are intended to be used as global properties that are settable on any type of object. In WPF/Silverlight, attached properties are typically defined as a form of a dependency property that does not have the conventional property 'wrapper'.

Download source code

 
2.       What attached properties are?
The main ability of the attached properties is to allow different child elements to specify unique values for a property that is actually defined in a parent element. In our example bellow I will show how a child element can inform its parent of how it is to be presented in the user interface (UI). Lets use the widely spread example of how the DockPanel (please note that the DockPanel exists only in WPF but not in Silverlight) uses the attached properties. When you add an element to a DockPanel, you need to tell the DockPanel on what side to Dock the element (Left, Right, Center etc.). In WPF the Dock property is an attached property registered by the DockPanel while in WinForms the Dock property is hardcoded in the Control class, even though you are not always docked. The Dock property only makes sense to the docking code.
 
Bellow you can see how to assign value to an attached property from within C# and XAML:
 
C#
DockPanel.SetDock( uiElement, DockStyle.Left );
//or
uiElement.SetValue( DockPanel.DockProperty, DockStyle.Left );
 
XAML
<DockPanel>
<ButtonDockPanel.Dock="Left"/>
</DockPanel>
As you can see here the attached property is DockPanel.Dock and the DockPanel is the property provider that has registered it internally. This registration is explained later in our example.
 
3.       Why we need attached properties?
The attached properties are a very powerful tool for dynamic extension of classes without inheritance. They also allow us to keep the properties located at their logical places – use what you need only when you need it. Moreover they allow the place, where the property is defined and the place, where it is stored, to be completely different classes that know nothing about each other. Like in the above example the Dock property value is stored in the button instance not in the DockPanel itself.
With the attached properties you can make your classes structure much more comprehensible for the developer by using only the properties that are valid in the specific context.
 
The good news is that many advantages from the dependency properties model are coming out of the box for the attached properties such as caching, data binding, default values, expressions, styling (which is nothing more than a set of predefined property values), property invalidation and more.
 
4.       Registering and using custom attached properties in Silverlight
Probably the first most important thing to mention here is that only inheritors of DependencyObject can be extended with such attached properties. This is needed because either to set or to get value for a specific attached property, you need to use the methods SetValue and GetValue which are defined in DependencyObject class. As we have already said all values defined for a specific attached property are stored in the instance of the extended object, so it acts like a regular hash table for the defined properties and their values.
 
The property provider class itself does not need to derive from DependencyObject, but Microsoft recommends making it also an inheritor of the DependencyObject, because thus we will follow the overall WPF model.
 
Let’s look at the most important steps needed to define a custom attached property in Silverlight:
1.       Define a hollow class that should act as the provider for the attached property. In our sample it will be named TabPanel and it derives directly from the StackPanel class.
 
public class TabPanel : StackPanel
{
publicTabPanel()
{
}
}
 
2.       Define the attached property as a field of type DependencyProperty inside the TabPanel class.
 
public static readonly DependencyProperty TabStopProperty = DependencyProperty.RegisterAttached(
        "TabStop",                   //Name of the property
        typeof( bool ),              //Type of the property
        typeof( TabPanel ),    // Type of the provider of the registered attached property
                null );                           //Callback invoked in case the property value has changed
We make this field public and read-only. Thus other people will be able to access it but they will not be able to change it. It is static because it describes a property that is valid for that class at all, not just for some specific instance of it.
3.       Define the appropriate SetXXX and GetXXX methods inside the TabPanel class.
 
public static void SetTabStop( DependencyObject obj, booltabStop )
{
obj.SetValue( TabStopProperty, tabStop );
}
 
public static bool GetTabStop( DependencyObject obj )
{
return ( bool )obj.GetValue( TabStopProperty);
}
As you can see these methods represent simple static type-safe wrappers for the GetValues/SetValue methods of the extended dependency object.
Note that every attached property must have such methods defined because they are used by Silverlight when the value of the attached property should be changed from within XAML. The naming convention is pretty straightforward ‘Set + Property name’ and ‘Get + Property name’.
 
4.       Here is how our TabPanel class finally should look like:
 
public class TabPanel : StackPanel
{
                public static readonly DependencyProperty TabStopProperty = DependencyProperty.RegisterAttached(
                         "TabStop",                  //Name of the property
                         typeof( bool ),             //Type of the property
                         typeof( TabPanel ),   //Type of the provider of the registered attached property
                         null );                           //Callback invoked in case the property value has changed
 
                publicTabPanel()
                {
                }
 
                public static void SetTabStop( DependencyObject obj, booltabStop )
                {
                         obj.SetValue( TabStopProperty, tabStop );
                }
 
                public static bool GetTabStop( DependencyObject obj )
                {
                         return ( bool )obj.GetValue( TabStopProperty );
                }
                //Just a sample method ilustrating the idea how to obtain the value
                //of the TabStop property for a specific element.
               
private void ProcessTabKey()
                {
                         foreach ( UIElement element in this.Children )
                         {
                                               bool tabStop = TabPanel.GetTabStop( element );
                                               //Perform some processing according to the tab stop.............
                         }
                }
}
There is only one thing left to be added to the TabPanel class and this is the implementation of the sample method where the value of that attached property will be used. I named this method ProcessTabKey and in our sample its tasks are to obtain the tab stop value for every one of its child controls and make some processing according to this value.
 
5.       Finally we have to define value for our new attached property for a control. Here are a few samples showing you how to do it from within XAML or the code behind.
 
C#
TabPanel.SetTabStop( uiElement, true );
//or
uiElement.SetValue( TabPanel.TabStopProperty, true );
 
XAML
xmlns:local="clr-namespace:SilverlightShow.AttachedProperties.Demo;assembly=AttachedPropertiesDemo"
<TabPanel>
<Button local:TabPanel.TabStop="True"/>
</TabPanel>
Do not forget to include in your XAML files the namespace and the assembly name containing the class that has registered the attached property, even though it is in the same assembly where your XAML is.
 
5.       FAQ
a.       How to set value to an attached property?
You can set the value of an attached property both within XAML and from the code behind. There are a few samples of both cases in the article above but in general the logic is very simple. From your code behind you can call the method SetValue of the instance of the class that the property is attached to. You will have to pass two parameters. The first one is the dependency property and the second one is the new value for that property.
 
uiElement.SetValue( TabPanel.TabStopProperty, true );
 
The other way is to call the appropriate static SetXXX method which belongs to the class that provides/registers the attached property. Depending on the implementation, you will need to pass some parameters that usually are the class whose property value should be changed and the new value for that property.
 
TabPanel.SetTabStop( uiElement, true );
 
The syntax in XAML is much easier. You just have to define the value for that property by typing its name like this ‘Provider.PropertyName’ where the Provider (i.e. TabPanel) is the name of the class that registers the attached property and the PropertyName (i.e. TabStop) is the name of that attached property.
 
<TabPanel>
                <ButtonTabPanel.TabStop="True"/>
</TabPanel>
 
b.      What kind of objects can be extended with the attached properties?
You can attach properties to any class in Silverlight that derives directly or indirectly from DependencyObject.
  
c.      What happens if we set value to an attached property, which property is not appropriate in certain context?
What if I define value for the TabStop property of a button but that button isn’t contained within a TabPanel? What should happen in that case? Will we get an error? The answer is that this won’t harm your application at all. If you define value for an attached property that is not needed, this won’t lead to an error. This value will simply never be used because no one will ever look for the property.
 
d.      How to register a custom attached property?
You can register an attached property by calling the static method RegisterAttached that belongs to DependencyProperty class. You can make the registration when declaring the static field of DependencyProperty type or in the static constructor of the class acting as a provider of that new property. For more information about the needed parameters see the comments bellow.
 
public static readonly DependencyProperty TabStopProperty = DependencyProperty.RegisterAttached(
                "TabStop",                  //Name of the property
                typeof( bool ),             //Type of the property
                typeof( TabPanel ),   //Type of the provider of the registered attached property
                null );                           //Callback invoked in case the property value has changed
 
e.        Are there any performance issues when working with attached properties?
To be honest I haven’t had time to perform a through performance test so far but I think that if there is a delay it won’t be anything tremendous at all. For me it is something I can live with.
 
f.       Where is the value of an attached property stored?
The value of every attached property is stored in the class the property is being attached to. For example if you define value for the TabStop property of a button then this value is stored internally in the button, not in the TabPanel that registered it.
 
g.      Can I bind to an attached property?
      Yes, you can bind to an attached property. However, this feature is available after Silverlight 2.

h.        When should I use attached properties?
I did not find any hardcoded rules for this. But according to me you should use attached properties in case you do not want to pollute your class code with artificial properties that are required so as other external classes to function.
 
i.        When should I avoid using attached properties?
Attached properties are not universal painkiller. They have to be used carefully and only in cases they play reasonable role in your application design. Otherwise they might cause confusions and misunderstandings.
 
6.       Conclusion
As a conclusion I could say that the attached properties are a very powerful thing if you use them at the right place and in the right time. Personally I will put them in my toolbox and grab them every time my design requires such behavior.
Bellow you can find a short list of the advantages and disadvantages of the attached properties as I saw them.
Pros:
-          You can define the properties that are meaningful only to the class itself;
-          You can keep your structure clearer and comprehensible by avoiding the artificial properties required by external classes to function;
-          Many advantages from the dependency properties model are coming out of the box for the attached properties such as caching, data binding, default values, expressions, styling (which is nothing more than a set of predefined property values), property invalidation and more.
Cons:
-          Some extra work is required to define an attached property;
-          Confusing for someone who isn’t familiar with this concept;
-          Hardly sensible performance decrease.
 
7.       List of some attached properties in Silverlight
Below you can find a list of some of the attached properties available in .NET Framework. This list is a short reference that was not meant to be complete. I decided to put it here to give you an idea about the way Microsoft uses the attached properties.
Canvas.Top – Define the distance for a control from the top edge of its container;
Canvas.Left – Define the distance for a control from the left edge of its container;
Canvas.ZIndex – Z Index of the control;
Grid.Row – Define the row index for a control placed in a Grid container;
Grid.Column – Define the row index for a control placed in a Grid container;
ScrollViewer.HorizontalScrollBarVisibility – Define the visibility of the horizontal scrollbar;
ScrollViewer.VerticalScrollBarVisibility – Define the visibility of the vertical scrollbar;
ToolTipService.ToolTip – Define the tool tip associated with a control;
and many more….
8.       Useful links/Resources
http://msdn.microsoft.com/en-us/library/cc265152(VS.95).aspx - See what Microsoft tells about the attached properties in Silverlight 2;
http://blogs.msdn.com/bencon/archive/2006/07/24/677520.aspx - Attached properties the basics with nice example by BenCon’s.
http://www.nikhilk.net/Entry.aspx?id=194 – How to create default commit behavior using attached properties by Nikhil Kothari;

kick it on DotNetKicks.com


Subscribe

Comments

  • -_-

    RE: Attached Properties in Silverlight


    posted by Alex G on Jun 10, 2008 12:27

    Nice post... keep em coming!

  • -_-

    RE: Attached Properties in Silverlight


    posted by Paul on Mar 13, 2009 12:07

    You CAN bind to attached property. Search MSDN first.

  • iiordanov

    RE: Attached Properties in Silverlight


    posted by iiordanov on Mar 13, 2009 13:00
    Hi Paul,
    at the time this article was written, this biding was not possible.
    I will update it next week, thanks for your feedback.
  • -_-

    RE: Attached Properties in Silverlight


    posted by Hemant Gaikwad on Jul 20, 2009 15:54
    Can you please provide me in details of Advantages and Disadvantages of Silverlight 3.0
  • -_-

    RE: Attached Properties in Silverlight


    posted by Maddy on Sep 29, 2009 10:35
    Good Article.
  • -_-

    RE: Attached Properties in Silverlight


    posted by Bob on Sep 30, 2010 20:50

    >Can you please provide me in details of Advantages and Disadvantages of Silverlight 3.0

    HA! I love questions like this. 

    Please to be providing details of how to create Word like word processor from scratch, in C#.

  • -_-

    RE: Attached Properties in Silverlight


    posted by bob on Oct 25, 2010 15:26

    Why even mention WPF?  And if you do mention wpf, why not explain that in wpf you can do something like

    <Grid ......  TextElement.FontFamily="Calibri">

    And all children of the grid that are based on TextElement will have that font set.  It doesn't seem to work in Silverlight.

  • -_-

    RE: Attached Properties in Silverlight


    posted by YJ on Oct 29, 2010 10:21

    about the performance issue...

    You said not tremendous in bullet "e".

    but you said " Hardly sensible performance decrease." in "Cons."

    what is your true thought about the performace?

  • TKelley

    Re: Attached Properties in Silverlight


    posted by TKelley on Jan 14, 2012 18:36

    I just got through reading a MVP rough cut chapter on Attached properties. This article was by far better than that one.  Thank you, I understand now!

Add Comment

Login to comment:
  *      *