Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Introducing Win8nl for Windows 8.1 – Kissing WinRtBehaviors Goodbye

DZone's Guide to

Introducing Win8nl for Windows 8.1 – Kissing WinRtBehaviors Goodbye

·
Free Resource

It was at my very first Summit in November 2011 that I learned that Windows 8 XAML was not to have any behaviors. I remember distinctly being very angry first, telling the presenter I would be “dead in the water”, then upon reflection, calming down, and deciding to find out if I could plug the hole myself. And so I did, with the help of (in order of appearance) Geert van HorrikFilip Skakun, and András VelvártWinRtBehaviorssaw the light in the early days of 2012. With 4,634 downloads, it being used in well-known top apps like Shazam, and being specifically mentioned at the 2013 edition of TechDays in both Belgium and The Netherlands (much to the surprise of colleagues and friends visiting there, not to mention myself) – I think I quite made my mark in the Windows XAML stack.

I also learned the downsides of having such a successful library, i.e. a lot of support requests. But todayVisual Studio 2013 was released, and along with it the final version of the Behaviors SDK, so I released a version of Win8nl – the library with ported Windows Phone code that I built on top of WinRtBehaviors – and I made a yet-to-release version of Catch’em Birds for Windows on it, that totally works (since very recently) on that new version of Win8nl. So the days of the old WinRtBehaviors warhorse are over.

Win8nl 1.0.9 still supports Windows 8.0 and still downloads WinRtBehaviors, but if you target your app for Windows 8.1 you will see that there’s not longer a reference made to it when you download the Nuget Package.

Part of the library are the classes Behavior and Behavior<T>. These have the following implementations:

using Windows.UI.Xaml;
using Microsoft.Xaml.Interactivity;

namespace Win8nl.Behaviors
{
  /// <summary>
  /// A base class for behaviors, can be used in native environments too
  /// </summary>
  /// <typeparam name="T"></typeparam>
  public abstract class Behavior : DependencyObject, IBehavior
  {
    public DependencyObject AssociatedObject { get; set; }

    public virtual void Attach(DependencyObject associatedObject)
    {
      AssociatedObject = associatedObject;
    }

    public virtual void Detach()
    {
    }
  }
}

This is a base class for environments where generics cannot be used - and the implementation for C# behaviors is then simple:

using Windows.UI.Xaml;

namespace Win8nl.Behaviors
{
  /// <summary>
  /// A base class for behaviors, to appear them to be identical to older frameworks
  /// </summary>
  /// <typeparam name="T"></typeparam>
  public abstract class Behavior<T> : Behavior where T: DependencyObject
  {
    [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]
    public new T AssociatedObject { get; set; }

    public override void Attach(DependencyObject associatedObject)
    {
      base.Attach(associatedObject);
      this.AssociatedObject = (T)associatedObject;
      OnAttached();
    }

    public override  void Detach()
    {
      base.Detach();
      OnDetaching();
    }


    protected virtual void OnAttached()
    {
    }

    protected virtual void OnDetaching()
    {
    }

  }
}

Based upon this class, you can port your existing behaviors from WinRtBehaviors (or from any other XAML framework, for what matters, virtually without any code change. I wrote this code in the early days of August, but kind of sat on it as I wanted it to be part of the new Win8nl library. I sat a bit on it too long, as Fons Sonnemans published a very similar solution in September, so I can’t really claim prior art, but let just say it’s a logical thing to do and great minds apparently think alike. I took the EditorBrowsable thing from him, never thought of that.

What you will also notice is that the ‘hero’ behaviors EventToCommandBehavior andEventToBoundCommandBehavior, although still present are now marked as Obsolete.This is for a very simple reason: the framework now has a standard way of doing such things. Would you use something like this in Windows 8.0 XAML:

<WinRtBehaviors:Interaction.Behaviors>
  <Win8nl_Behavior:EventToBoundCommandBehavior Event="Loaded" 
    Command="{Binding StartGame}"/>
  <Win8nl_Behavior:EventToBoundCommandBehavior Event="Unloaded" 
    Command="{Binding SuspendGame}"/>
</WinRtBehaviors:Interaction.Behaviors>

Now you can achieve the same thing an EventTriggerBehavior combined with an InvokeCommandAction.

<interactivity:Interaction.Behaviors>
  <Core:EventTriggerBehavior EventName="Loaded">
    <Core:InvokeCommandAction Command="{Binding StartGame}"/>
  <Core:EventTriggerBehavior EventName="Unloaded">
    <Core:InvokeCommandAction Command="{Binding SuspendGame}"/>
  </Core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>

I would urge you to the utmost no long to use EventToCommandBehavior and/or EventToBoundCommandBehavior again. Any support request will simply be directed to this blog post ;).

Something I have been sitting on for very long – part of Catch’em Birds for Windows was aDataStateBehavior, which I basically cobbled together by reflecting into a Windows Phone 7 assembly, butchering stuff I didn’t need, understand or that did not compile, and finally arriving at something that kind of worked. For my goals. For obvious reasons I could not publish what was basically stolen and butchered Microsoft code and I am therefore very happy the Behavior SDK now has something to do the trick. If you now use DataStateBehavior in for instance a Windows Phone project like this:

<behaviors:Interaction.Behaviors>
  <behaviors_ic:DataStateBehavior Binding="{Binding IsGameOver}" 
     FalseState="GameNotOver" TrueState="GameOver" Value="true"/>
</behaviors:Interaction.Behaviors>

You can achieve the same effect by using this code:

<interactivity:Interaction.Behaviors>
  <Core:DataTriggerBehavior Binding="{Binding IsGameOver}" Value="True">
    <Core:GoToStateAction StateName="GameOver"/>
  </Core:DataTriggerBehavior>
  <Core:DataTriggerBehavior Binding="{Binding IsGameOver}" Value="False">
    <Core:GoToStateAction StateName="GameNotOver"/>
  </Core:DataTriggerBehavior>
</interactivity:Interaction.Behaviors>

Thus ends the story of WinRtBehaviors on October 17, 2013. I hope you have enjoyed it, and I also hope to have given you a clear migration path.

I wish the development team lots of luck with the support requests from especially my Belgian friends, who were quite ingenious in finding scenarios in which the EventToCommand behaviors did not work properly. The best one was something like “the behavior does not work if it’s in a data template from a resource file located in another assembly”. ;)

Topics:

Published at DZone with permission of Joost van Schaik, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

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

{{ parent.tldr }}

{{ parent.urlSource.name }}