Essential WPF

November 2009 - Posts

Internet via Acer Aspire 1420p 3G

To all the lucky guys (like me :-) attended to the Microsoft PDC 09 conference last week, and won an acer touch tablet PC, here is how you can use the built-in 3G modem (yes it has such) to connect the Internet using your local cellular vendor.

First, make sure that you have a data package. Now do as follows:

  • Turn off your machine, and remove the battery
  • Insert your USIM+ card to the sim slot (you may hear the click sound while pushing)

Connect USIM Card

  • Connect the battery and turn on your machine
  • While logged in to Windows 7 turn on the 3G modem by switching the 3G button located in the front of the laptop panel (push it left)

Activate 3G

  • Click on the Windows 7 network tray icon and connect

Connect to 3G

  • A dialog may appear, asking for access point. You may call your cellular vendor, asking for details.
    • If you’re connected to Orange Israel, just place: uinternet in the access point (no user, no pass)
  • Surf the Internet.
Session - Building Extensible Rich Internet Applications with the Managed Extensibility Framework

In this great session, Glenn Block and my collegue Ariel Ben Horesh have talked about Managed Extensibility Framework for Silverlight 4 for building customizable applications that can easily be extended by third parties. Whether you are building an extensible data grid, a custom rules engine, a pluggable editor, or a composite application such as a pluggable CRM system, you want to learn about MEF. They explained how to use MEF to decouple applications into more maintainable the application into dynamically deployable chunks that download on-demand.

The managed extensibility framework (MEF) is a new library in .NET 4.0 and Silverlight 4 for building applications that can be extensible.

MEF takes parts and tier them together, like LEGO, based on the configuration of the user. The concept is that your application is built up from parts.

The basics, core concept to work with MEF are:

Export it

You can create a part and export it so it could be discovered and import to compose the application.

Import it

I need something, so you can import single or many parts.

Compose it

Now that you’ve got all of the parts, compose them together to compose an application.

For example, you have a dash board built of widgets. You can create widgets and export them. Just decorate the widget with the Export attribute. The widget itself can Import other parts. The dash board now can import one or many exports. In the Silverlight main page you should call PartInitializers.SatisfyImports() to satisfy all imports. This is it. Now MEF will automatically load and compose all parts.

Metadata

Provides meta information for exports, for example where the widget should be located by default, on the top are at the bottom.

To define metadata you should define types an and interface which defines the metadata, then export it using ExportMetadata and acquire it while import. While import you should work with the Lazy<P, M> instead of directly importing the par

Custom Attributes

In MEF, instead of using the out-of-the-box attributes (Import, Export) you can create your own. For example WidgetAttribute. In such case you should create an attribute and derive it from the MEF ExportAttribute.

Recomposing

In MEF there is an option for re-composition, meaning that MEF can be notified while new parts are added at run time. To turn this on you should set the Import.AllowRecomposition to true. Now if you download packages at runtime, MEF will be notified and compose the new parts.

Windows Presentation Foundation 4 Plumbing and Internals

In this session we saw the inside scoop on how Windows Presentation Foundation (WPF) powers all its rich services – like layout, databinding, and animation. There is a lot of heavy lifting done for you under the hood; in this session, we crack open these system components, including the trees (visual, logical, and inheritance), the property system and its change notification, and a few of the routing systems that all messages go through. Bring your hard-hat for this one!

WPF Involves lots of interacting concepts

  • Layout, Animation, Styles, Templates, Binding and Events

Windows constructore calling InitializeComponents, but layout and template expanding and other binding related are differed. We can’t assume that layout worked in the ctor.

Where are properties set?

Animated Value, Local Value, Setter in style trigger, Setter in style, Inherited value

Property values are often sought rather than set!

  • SetValue sets local value
  • GetValue get effective value

Set may destroy binding. SetCurrentValue instead of SetValue will do the job.

Binding in general

  • DataContext is inherited – Data template instances given explicit context
  • Some properties bound two-way by default
  • CollectionView – implicitly created when binding to a collection. Tracks “current” item
  • Binding expressions now work with .NET dynamic type

Inheritance

The logical tree is the containment part of the tree.

  • Templates expanded lazily during layout
  • Inherited properties trace inheritance context
    • First preference is logical parent
    • When not present uses visual parent
  • Freezable subtypes have a special inheritance context
    • Shared freezables (using the XAML x:Shared keyword) inherit based on where they are declared, non-shared based on where they are used
  • In WPF 4.0, InputBinding is now freezable – can take advantages of the inherited context

Dispatcher serializes everything

  • Dispatcher runs on UI thread
    • All DispatcherObjects associated with dispatcher, single-threaded
    • Processes a prioritized work queue

We can break long tasks into Bite-Sized Pieces.

  • Use Dispatcher.BeingInvoke, process work in priority order
  • Priority can be changed after scheduling
  • DispatcherTimer schedules work as inactive, uses Win32 time to update

Use threads:

  • WPF Render Thread – WPF internals only
  • UI Thread(s) – UI Construction, Event listeners, Layout, Binding etc.
  • Worker Thread Pool – 100% User Code

Long-running and blocking operations belong to worker threads. Avoid DispatcherObject in non-UI threads.

You can use BackgroundWorker to save the threading pain.

Visuals and framework elements do a lot of work. Avoid premature optimization. You can use Snoop with memory and profiling tools to investigate observable issues. Consider OnRender()

Before cutting down the number of visuals in the visual tree, try to figure out where the real problem is. WPF can handle thousands of visuals per second.

Virtualizing Visual Trees

If you replace the items panel in an ItemsControl, try to use the VirtualizationStackPanel instead of StackPanel, it performance much better. DataGrid in WPF 4.0 support VirtualizationPanel.

Session – Advanced Topics for Building Large-Scale Applications with Microsoft Silverlight

In this session, John Papa talked about Silverlight application development patterns such as composite applications with Prism, developing using the Model-View-ViewModel (MVVM) pattern, and methods of implementing large, modular, multi-page applications within your team. Also he talked about frameworks created to help assist in rapid development using these patterns without sacrificing good application development patterns.

MVVM is a pattern, there is no specific way to do it right. Also with Silverlight.

MVVM, MVC, MVP and MV??? are all commonly accepted patterns for maintainable, scalable and testable applications. People look for patterns to describe common way for programming UI.

MVVM is a separation of concerns. Provides loosely coupled UI from logic, good for testing.

Model

The model represents the data, it only a data entity. Not required to know where it gets its data from. Easy to test and to maintain.

ViewModel

Main source of logic for the MVVM triad. It connects the Model to the View. It abstracts the View and provide public properties to be bond with the view. This separation is great for unit testing.

MVVM Variations

View First – ViewModel is declared as Static Resource in the View’s XAML. Works well in Expression Blend. Another way is to create ViewModel in the View’s code-behind.

ViewModel First – view is injected into the ViewModel’s constructor. For example, ViewModel is created first then view is bound with the ViewModel.

View and ViewModel using Intermediary

An intermediary creates both the view and view model, then connect them together.

Prism 2

Prism is set of options, you can use what you want and ignore the rest. In the MVVM case you can just use the module catalog but ignore the Event Aggregator.

The rest of the session was what is prism and how to use it. So I’ll save you the pain.

Session – Building Line of Business Applications With Silverlight 4

In this nice session David Poll has talked about enhancements to data binding and data validation as well as new support for rich text & printing in the platform that allow you to build compelling LOB user experiences.

Everyday we work with data so we usually deal with Interactivity, Entry and Presentation

In this talk he explained about features added to SL 4

  • SL4 in Visual Studio 2010
  • Data Binding enhancements
  • Data related controls enhancements
  • Input validation
  • Printing a document

David shown an Issue Tracker application as a case study. The application connects to a DB, gets the data from and visualizes it.

Master View Binding

To display a data grid in VS 2010 you can drag-drop a table directly to a canvas. VS 2010 will create a bound data grid automatically. Then you can select the data grid and set its properties using the property grid. You can group items using CollectionViewSource. It now supports grouping!

Details View Binding

Now you can display a details view for item selected inside the grid. Create a simple user control with all the fields then set the master details. VS 2010 provides binding UI provides option to bind to the bound Data Grid selected item. Now both views are synchronized.

Foreign Key Relationship

Using the VS 2010 data binding you can bound an item by support foreign key relationship. You can bind the SelectedValue to the foreign key. Also you can select a string format.

Dictionary Binding

Binding a dictionary is also possible, just bind the element to the string index of the dictionary key.

Command Binding

Continue with the demo, David showed that SL4 supports ICommand. Selecting a button you can bind it via Command property to any command implementing the ICommand, and the command implementation could be implemented by the View Model using MVVM.

INotifyDataError Interface

SL4 is now supporting the INotifyDataError interface for error validation on the data model. So you should only implement the INotifyDataError interface in the model object and that’s it (BindingBase.ValidatesOnNotifyDataErrors is set to true by default so you don’t need to specify it). Also you can add a data validation asynchronously (for example calling a services for validation async, then get the result).

Printing a Page

To print a page using SL4 you should create a PrintDocument instance, initialize it, set properties, events and call Print. You can use any control to render the content for printing. Just create a user control, create an instance of it within the start printing event handler, and set the instance as the PageVisual property of the start printing event argument.

Silverlight 4 added a lot of more interesting features not listed in this session. You may check Alex’s blog for a deeper overview of the new features in SL4.

Session - Media Foundation: Supporting Hardware Codecs and Cameras

In this very intersting session, Stan Pennington talked about how Windows 7 adds support in native code for accelerating media transcoding and specific playback experiences through the new asynchronous Media Foundation transform (MFT) model. How to write and use accelerated MFTs, and how to license for preference in Windows Media Player and portable device operations with Windows Shell. He showed a managed sample using the transcoding API, and showed how the new Device Proxy simplifies AVStream driver based video capture in Media Foundation. Talked about in-box support for high-definition UVC webcams and the new extensibility model, along with how the new native Source Reader object allows easy capture integration into existing applications. Finally, demonstrates new tools for developing and debugging in Media Foundation.

MF Provides Hardware Codecs and Async support, HD Webcams support.MF Focused on unmanaged API – coding, transcoding must be really time, buffering, good response to flashing and other. Writing unmanaged you’ll have twice as faster comparing to managed, the GC is non-deterministic.

MF could expose configuration, control and status through managed APIs.

There are four media infrastructures Microsoft deals with:

  1. Video for Windows – ACM Codecs
  2. DShow – DVD, TV )Filter, DMO, ACM, VCM)
  3. Direct Show – WM True Streaming (DMO, ACM Codecs)
  4. WM FSDK – Key mainstream scenarios & nre features (MFT Codecs)

Media Foundation is the area Microsoft is investigating these days for media.

Typycal Microsoft usage in Windows 7

  • MF – Playback for non streaming ASF, MP3, MPEG-4 and selected AVI permutations of digital still cameras
  • New metadata handling in Shell Property Handlers
  • Transcoding and new media sharing
  • DShow – DVD, TV, MPEG-2, MPEG-1, custom I/O, video editing
  • FSDK – Best compatibility for ASF true streaming
  • Historic integration of ASF read, write.

Microsoft uses the whole three main infrastructure to get best end use experience. Windows media center uses WMP OCX with custom presenter.Window 7 change protected media path (PMP) in WMP and OCX.

Windows Vista PMP used for MF even with unprotected content, providing seamless cross-fade in mixed DRM/non-DRM playlists. Windows 7 PMP only used for DRM-protected content in MF.

Why should we use MF?

  • Stream objects (IStream) for media input, output
  • Most connectivity and data flow divorced from streaming components, moved to higher layer
  • No push-pull component issues
  • Better potential for dynamic changes
  • Better control of threading
  • More constrained components roles and graphs topologies
  • Hardware Codecs – transcoding only or general for transcoding and playback

To have WM, you should install Windows 7 SDK.

Session - Advanced WPF Application Performance Tuning and Analysis

In this great WPF performance session, Bart De Smet and Eric Harding have talked about WPF performance and demonstrates some of the performance tools the WPF team uses.

One of the important things to do regards performance is to start measure early. Perceived performance, make it feel fast, turn it to an art and not a science. There would be trade offs – CPU versus memory, etc.

Memory

New WPF application called FishBowl has been announced. It’s a small application dealing with facebook as a case study.

To profile memory do:

  • Run the application
  • Open process explorer (the app wastes 150mb)
  • Open VMMap to break down memory usage and shows where memory is going Both in native and managed heap.
    • Render uses native memory
    • Images uses native memory
  • Open .NET Memory Profile – WPF team uses it – see where memory was allocated
  • Look at the shortest root path to know who holds the objects

 

Cold Start

To profile cold start do:

  • Prevent unnecessary DLLs from being loaded
  • Set xperf to run at startup – this shows how much CPU by process also disk IO
  • Use .NET memory profiler again to know what object was loaded

IMG_1857 

Warm Start

To profile warm start do:

  • Run the application
  • Use WPF Perf Visual Profiler, and attach to application to analyze the visual tree (how many elements loaded)
  • Use CPU profile such in Visual Studio Profiler to look for the hot path with higher CPU time

IMG_1860 

Runtime

To profile runtime do:

  • Use WPF Perf Visual Profiler to see were CPU spend its time
  • Use perforator to see rendering performance
    • High IRTs (GPU) may effect frame rate – effects, clips, opacity and opacity mask
    • Element count may increase IRTs – input and routed events
  • In .NET 4.0 here is a Cache Composition trading video memory with CPU

IMG_1864 IMG_1863 IMG_1865

 

Runtime Best Practice

  • Don’t block UI thread
  • Use UI Virtualization and Data Virtualization when possible
  • Freeze your freezables – no change notification callbacks
  • Hardware vs Software
    • RDP, virtual machines, old hardware
    • RenderCapability.Tier
    • Reduce frame rate, 3D rendering

IMG_1866

This is it for this session. In a future post I’ll describe this process in more details.

Session - How Microsoft Visual Studio 2010 Was Built with WPF 4

Paul Harrington talked about the new WPF UI of Visual Studio 2010, the start page and many other designers, displaying the Visual Studio 2010 WPF visual tree using Snoop.

image

Architectural reason is one of the reasons Visual Studio 2010 has been reprogrammed to use WPF 4.0. Separated presentation and support for long range road map.

He also explained that VS 2010 features really need it: Editors, Architect designer editor, Parallel tools, Workflow designer and more

Another reason is to make it easy to develop new features in VS 2010.

Here are several features added to VS2010 for WPF:

  • Declarative UI using XAML
  • Data binding managed and native data models
  • Styling Templates
  • Application resources
  • Interop with Win32
  • Integration with the message loop
  • New text stack based on DirectWrite

After explaining why using WPF in VS2010 he talked about the how.

  • Defining the data models
  • Replacing the VS main window with WPF (creating window without displaying it)
  • Write new components: Command Bar, hidden behind switches off by default
  • Scouting with selected teams
  • Lot of testing
  • Leaving old presentation for regression testing
  • Removing old code

He mentioned that testing conversion costs, and the main reason was that there are no HWNDs in WPF!

Testing of the new VS 2010 yields unify test frameworks based on UI Automation, and best practices. One of the important one was test at data layer, means Separated Presentation is important!

The challenges the VS 2010 team were:

  • Mixed mode application – native and managed code, WPF and HWNDs
  • Allow new extensions to take advantage of WPF (creating plug-ins for VS using pure WPF)
  • Text clarity since WPF blends colors in small text becomes blurry
  • Performance – Beta 2 is lot more better than Beta 1, and there is lot more work to do. This is the key issue for next

Challenges of Mixed-Mode

  • Managed code binding to native models
  • Interop in the presentation layer (especially in focus mechanism)
    • Added new features to WPF to better support focus
      • HwndSource.AcquireHwndFocusInMenuMode
      • InputManager.EnterMenuMode and InputManager.ExitMenuMode, PushMenuMode, PopMenuMode and more
      • Integration with message loop
  • Text and image clarity stack: TextOptions.TextFormattingMode removes the blur from text

Performance Issues

  • Switching tab – it is highly recommended to keep the load operation atomic as possible. Make sure that the visual tree you switch to would be fully ready before switch
  • Memory usage using tools such as VMMap (look at image load), SOS.dll, !dumpheap-stat
  • Windows performance analyzer (xperf)
  • Hardware vs software rendering (Virtual Machines and Remote Desktop) – Gradient fill is more expensive in remote desktop, using solid brushes instead
  • Scrolling in the editor

Who were involved:

Core team of about 12 people, 7 developers and 5 testers, the WPF Team and the Expression Suite Team

Live from PDC 09 Keynote – Product Maturity

The cloud computing, Windows Azure, System Center and server tools for Windows and more platforms Azure tools for Java and Eclipse are the main topics that Ray Ozzie has mentioned. You can get more details from Noam’s and Alex's blog, he is a great writer :-)

Ray also announced Dallas CTP for discovery, exploring and using data in a new way.

In the bottom line azure is much more mature than the last year, and there are many new tools for hosting applications in the cloud.

Waiting for more information about Windows Phone and Silverlight next.

Live from PDC 09 Keynote

We are here, 20 people from Sela Group, wearing blue, waiting for the PDC 09 keynote to begin. The hall is full of people, and there are many other entering, seeking a seat.

IMG_0950 IMG_0951 IMG_0952

Comparing to PDC 08, there are less people, and its of course due to the economic situation, but the decoration here in the hall is awesome, and we’ve already got 3D glasses… I’m too curious to know why.

Ozzie is here… please excuse me, I’ve got something to do here… :-)

Blend Behaviors via Attached Properties – Part 3

Recall my previous post, I’ve talked about how to implement custom Actions. In this post I would like to explain how to implement custom Triggers.

As you may already know, trigger is the cause and action is the effect of that cause.

The question is, why would you like to implement a custom trigger?

So lets start with a little example: Blend 3 comes with only event triggers. But what if you want to invoke an action when property changes?

For that reason you would like to implement a custom trigger. This custom trigger will have a property name as an input, and from that moment it will listen to that property change notification.

Implementing a custom trigger is easy as deriving from the TriggerBase<T> base class, overriding the OnAttached/OnDetached methods accordantly for defining the trigger behavior.

In our case, we are overriding the OnAttached method to extract the relevant property, and then to register its value change. In the value change event handler, we are calling the InvokeActions base method for activating associated actions.

public class PropertyTrigger : TriggerBase<DependencyObject>

{

    private DependencyPropertyDescriptor _propertyDescriptor;

 

    protected override void OnAttached()

    {

        base.OnAttached();

 

        if (Property == null)

        {

            return;

        }

 

        // Get the property type descriptor and register to value change

    }

 

    protected override void OnDetaching()

    {

        base.OnDetaching();

 

        // Unregister from value change

    }

 

    private void ValueChanged(object sender, EventArgs args)

    {

        // Call InvokeActions here

    }

 

    #region Property

    public string Property

    {

        get { ... }

        set { ... }

    }

 

    ...

}

To use this custom trigger, you should drop an action, go to the action properties, select New on TriggerType and pick the PropertyTrigger.

image

Now that we can create custom triggers, we can have more triggers in our actions toolbox, simplifying the design phase and make the UI designer happy :-)

You may download the full code from here.

In my next post I’ll talk about implementing custom behaviors, so stay tuned.

Live from PDC09

We are here!

20 people from Sela Group are proud to be part of the PDC 09 great conference. We are here for updating you with the most up to date Microsoft technologies.

I’m going to concentrate on the following topics:

  • Windows 7 Development
  • Visual Studio 2010
  • WPF 4.0
  • Silverlight
  • UI Architecture

So prepare your RSS reader and stay tuned, we are going to blast this blog server with great stuff directly from the PDC halls.

Blend Behaviors via Attached Properties – Part 2

In my previous post I’ve talked about Blend 3 attached behaviors, and explained how to use them. In this post I would like to dive into more details, explaining the differences between Triggers, Actions and Behaviors types and how to create custom triggers.

Triggers and Actions

Actually blend 3 attached behavior comes in two flavors:

  • Triggers and Actions
  • Behaviors

You can think of triggers and actions as cause-and-effect relationships. Trigger represents the cause. For example we want to do something when routed-event is raised or property has changed. Action is the effect caused by, for example we want to navigate to the next page when routed-event is raised, so “navigate to next page” is the action and “routed-event raised” is the cause of that action.

Behaviors

While action is invoked only by a trigger, behavior has its own invocation logic and it’s not depended on any trigger.

Custom Action

Using Blend 3 SDK we can easily extend each element described so far. In this post I’ll concentrate on how to create a custom action.

Lets say that we want to create a custom action that displays a simple message box when invoked, with specific parameters.

So first thing we have to do is to install Blend 3 or Blend 3 SDK.

Now we should do as follows:

  1. Add reference to System.Windows.Interactivity.
  2. Create new class called ShowMessageBoxAction derived from TriggerAction<DependencyObject>. TriggerAction<T> represents a trigger base class where T is the associated type.
  3. Add dependency properties for each one of the required message box parameters.
  4. Override the Invoke method to show the message box.

    public class ShowMessageBoxAction : TriggerAction<DependencyObject>

    {

        #region Overrides

 

        protected override void Invoke(object parameter)

        {

            MessageBox.Show(Message, Caption, Buttons);

        }

 

        #endregion

 

        #region Dependency Properties

 

        public string Message { ... }

        public string Caption { ... }

        public MessageBoxButton Buttons { ... }

 

        #endregion

    }

Note that you can place all actions in a different assembly, and add a reference to it.

Now looking at Blend 3, we should see our custom action.

image

To use the ShowMessageBoxAction all we have to do is to create a simple button for example, drag-drop this action on the button we’ve just created and set the action’s trigger (cause) and properties.

image

You may download the source code from here.

 

If you enjoyed reading this post feel free to keep tracking. In my next post I’ll explain how to create custom triggers.

Blend Behaviors via Attached Properties – Part 1

Up until Blend 3, UI designers had difficult time prototyping a real functional UI. The main problem was the lack of behaviors. Creating a UI prototype that deals with navigation, window creation on event, animation on data changes etc, usually ends up with source code development. And when it comes to coding, UI designers had to have kind of developer colleague.

XAML Tools

Over time, developers (like me :) created many XAML extensions using both XAML Markup Extensions and the powerful Attached Property mechanism. See this post for example. The main problems with such an approach are the lack of Blend support (no simple drag-drop mechanism for using those tools) and standardization.

Attached Behaviors

Blend 3 offers many new features for UI designer, and I think that the most powerful feature in Blend 3 is Attached Behaviors. You can think of an attached behavior as an action triggered by an event or property change and that could be attached to any visual element. For example clicking on a button, we want to change a visual state, navigate to different page or even popup a window. The great thing in these behaviors is that they use the same approach as many developers use to create their XAML tools I’ve described above, which are attached properties, and thanks to Blend 3 it’s very simple to use attached behaviors. You should just pick a behavior and drag-drop it on an element.

Using Behaviors

Lets say that you’ve designed a prototype with one or more buttons to control animation, and you want to start and stop the animation by clicking the buttons. In addition to that you want each button to be disabled if not relevant. As a UI designer it looks like I have to deal with logic, and logic is code!

Using Blend 3 behaviors we can easily achieve that as following:

  • Create the animation scenario.
  • Create start and stop buttons.
  • Go to Assets –> Behaviors in Blend 3.

image

  • Drag-drop ControlStoryboardAction behavior to the Play button and set the behavior’s properties to start the animation you’ve just created.

image image

  • Drag-drop ChangePropertyAction behavior to the Play button and set the behavior to disable the button.
  • Drag-drop ChangePropertyAction behavior to the Play button and set the behavior to enable the stop button.
  • Repeat these steps for the stop button.

 

Resources

For additional behaviors, go to Expression Gallery and search for the term “behavior”.

You may also find David Hill’s approach to Helix navigation using Blend behaviors very interesting.

You may download the demo code from here.

In the next post I’ll explain how to extend blend behaviors and demonstrate how to create custom behaviors.

<howto> Start Animation on Model property changed </howto>

Lately I’m teaching UI designers to work with WPF, and one of my students asked me how to start an animation when model’s property changes, and this was my answer:

If the animated element is part of a DataTemplate, use DataTrigger to monitor data changes and to start the animation. But if you don’t have a DataTemplate or the animated element is not part of the DataTemplate, create a Style for that element, and use a simple DataTrigger within.

<Style x:Key="PathStyle" TargetType="{x:Type Path}">
    <Style.Resources>
        <Storyboard x:Key="DataChangeAnimation">
            ...
        </Storyboard>
    </Style.Resources>
    <Style.Triggers>
        <DataTrigger Binding="{Binding Path=IsDirty}" Value="True">
            <DataTrigger.EnterActions>
                <BeginStoryboard x:Name="DataChangeAnimation_BeginStoryboard"
                                 Storyboard="{StaticResource DataChangeAnimation}"/>
            </DataTrigger.EnterActions>
        </DataTrigger>
    </Style.Triggers>
</Style>

Be aware that if you use a style, you can not specify the TargetName, hence you should create a Style for the animated element and place both the animation and data DataTrigger inside.

Feel free to download the source from here.