Posted by on May 30, 2016 in #uwpdev | 2 comments

XAML is an incredible markup language for both prototyping concepts and building rich, fluid experiences. The set of capabilities is large, and for some a bit unexplored. One of those areas is a concept called attached properties. An attached property is essentially a global property, which can be set on any object.

Attached properties have been around even in WPF (Windows Presentation Foundation), but this post is directed towards attached properties in the Universal Windows Platform. They are however much similar. Get started with UWP (Universal Windows Platform) development here: https://msdn.microsoft.com/library/windows/apps/xaml/dn609832.aspx#target_win10

So what does attach properties actually solve? There are many use cases, one is to reflect unique values in child elements of a parent. So that the parent can use these values and apply necessary logic (e.g. docking settings). Another use case is surrounding custom animations.

There are many built in animation capabilities in XAML, and you also have the ability to create your own custom animations. Applying your custom animation on many elements may result in very large and repetitive resource in your XAML. These will be consuming to maintain and update.

To get around this problem, you can use attached properties. The following example consists of three elements, applying the same animation – but without cluttering down your XAML markup. Attached properties can help us to create a single process for applying our custom animations.

Animation2

Its markdown looks like the following:

Rather tiny and great for code readability and reuse. What has been introduced is three different (attached) properties, located in the xamlExtensions namespace.

  • ElasticUI.IsEnabled: Triggers wither or not to inject needed resources into the FrameworkElement.
  • ElasticUI.AutoStart: Configures the event handler for the Loaded event – which ultimately triggers the animation if requested.
  • ElasticUI.StartDelay: Used when starting the animation – either right away or with a delay.

The more elements in need of this particular animation – the more code we can reuse using attached properties. Notice that I will be using the FrameworkElement object as the base throughout this blog post – this is because the FrameworkElement is what defines the Resources property, which we need for storing the animations (Storyboard).

Anatomy of an Attached Property

An attached property is defined pretty easily, and can be done in a few different flavors. Be sure to create a public containing class for the attached properties – as XAML needs to be able to access your class. I defined mine as such:

In addition, I made my class static as all of the operations and properties would be static. Now the first step is to define the DependencyProperty.

You are required to specify the property name ([PROPERTY_NAME]) and property type ([PROPERTY_TYPE]). The DependencyProperty object does a lot more for you than just hosting getters and setters. For instance, they care of the logic needed to notify the view about changes when using bindings.

To complete the attached property, you will need to create the getter and setter methods. They are static implementations which will reflect the value onto the DependencyObject itself (the FrameworkElement in our case). Make sure to specify the same property name and property type for the methods.

Injecting Storyboards

When inserting resources into a FrameworkElement using an attached property, you will most likely be doing so using C# or any other language supported in the UWP. While some things will still be very natural to keep in your global resources, you should do so. But as soon as you notice that you’re duplicating pieces, it could be time to think about an alternate route.

Storyboards are a bit tricky, because they need to be attached to a DependencyObject – they can be a hassle to reuse. It’s also not meant to work with multiple targets. You can run into odd behaviors if you’re trying to switch targets during different states of the Storyboard (such as value resets, etc.). A better approach would be to have a separate Storyboard for each FrameworkElement, but that gets you into the repetitive problem. Attached properties can reduce the repetitiveness for you – while still maintaining the notion in XAML that we are doing something underneath the hood.

The Storyboards injected via code should absolutely leverage styles and values from the global resource dictionaries if needed. As done below (view Merged resource dictionaries at: https://msdn.microsoft.com/en-us/windows/uwp/controls-and-patterns/resourcedictionary-and-xaml-resource-references).

You can access the global resources via the Application.Current.Resources property.

Now using the above, and the anatomy of an attached property. I proceeded to implement the ElasticUI class as such:

ElasticUI.IsEnabled checks if it needs to create the Storyboard and add it – or simply remove it from the FrameworkElement’s resources. It also hooks up the Loaded event for the element, which will automatically start the animation if the ElasticUI.AutoStart property is set to true. If it is, it will acquire the ElasticUI.StartDelay value and hold for the requested time if needed.

The final step is to reference the ElasticUI class (or your own class for the attach properties) in the XAML views:

My final view looked like this:

When launching, the following result is produced:

Animation2

The XAML view is extremely clean and easy to read. All of the animations originate from a single injection process, which allows you to make modifications and changes in the future – which will apply to all of your instances.

This is merely a simple illustration of what can be achieved using attached properties. You can get much more complex by hooking into more events and creating bindings. If you want to learn more about UWP development, head to: https://msdn.microsoft.com/library/windows/apps/xaml/dn609832.aspx#target_win10

-Simon Jaeger