Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Silverlight Experimental Hacks (SLEX) - EventTrigger, PropertyTrigger, ReactiveTrigger, InvokeMethodAction, StoryBoardAction, etc. for Silverlight

0.00/5 (No votes)
14 Jan 2010 1  
A set of Silverlight Experimental Hacks (1) A custom implementation of EventTrigger and PropertyTrigger (2) Invoking methods in your view model in MVVM (3) Conditionally invoking triggers and behaviors (4) ReactiveTrigger for exporting your custom events

What is there in Slex?

If you are familiar with Silverlight/Expression Blend, you should be knowing about the System.Windows.Interactions infrastructure – which provides various Behaviors, Triggers, and Actions.

Go through these articles if you want to refresh:

  1. Introduction to Behaviors and Triggers
  2. Behaviors and Triggers in Silverlight

Good news!!: Recently, I ported most features of Slex to WPF - under the name WEX, or WPF Experimental Hacks. Check it out here in CodeProject. The source code of Slex is in Silverlight 4.0/VS2010 because of the dependency object bindings, but Wex is in .NET 3.5/VS2008.

Slex is an experimental implementation of some additional Triggers and Actions on top of the System.Windows.Interactions, along with a few extension points. (You may also note that Expression Blend already provides you a handful of Triggers and Actions; I've mentioned about how Slex relates to them towards the end of this article.)

Slex can serve you if you are interested in learning how to implement your own Triggers, Actions etc., for Silverlight, and brings to the table some interesting experiments (my favorite is the ReactiveTrigger).

Before we explore what is inside Slex, have a look at what it can do. Here is a screenshot of the demo application:

image

Triggers in Slex, and Actions inside them, can be invoked based on conditions:

image

These are some notable aspects in Slexthat are not available in the Triggers and Actions available with Expression Blend.

  • Slex allows you to define multiple conditions for invoking Triggers (like you can specify a KeyDown event trigger should be fired only if 'A' is pressed)
  • You can specify multiple conditions for invoking each Action in a Trigger
  • Slex introduces a few more Triggers and Actions that you'll see soon

As of now, Slex Preview 2 provides the following Triggers:

  • EventTrigger – Will be fired when an event is raised. Can listen to events of Elements, or events from your View Model.
  • PropertyTrigger – Will be fired when the specified property changes. Can listen to properties of Elements, or properties in your View Model.
  • ReactiveTrigger – Can 'import' an Observable that you may 'export' using MEF. Useful to define and use custom events using System.Reactive.

And the following Actions:

  • InvokeMethodAction – Invokes a method directly in the View Model or for a target element, supports passing parameters via XAML
  • InvokeCommandAction – Invokes an ICommand in the View Model
  • StoryBoardAction – Start, Stop, Pause, Resume, or Reverse story boards
  • PropertyAction – Sets a property value (very crude as of now)

You can specify one or more InvokingConditions for Triggers and/or Actions. Also, Actions like InvokeMethodAction and InvokeCommandAction have an ActionParameters property, so that you can pass one or more parameters when invoking methods and commands.

Conditionally Invoking Triggers and Actions

Let us see a simple example on a scenario – You need to start a story board when a button is pressed, but you need to do that only if a particular checkbox is checked. Assuming your Button is btnBegin, your StoryBoard is myStoryBoard, and your CheckBox is chkMain, this is something that you can do (see the StoryBoardAction demo):

image

If you look at the above code, you may find that we are specifying various conditions for the Trigger itself – all Actions in the Trigger will fire only if all the Invoking Conditions are True. You should be able to place other Actions (that come with Expression Blend, your own custom actions etc.) within an EventTrigger, PropertyTrigger, or ReactiveTrigger – to execute them conditionally.

Also, you may need to specify conditions for invoking each Action in the Trigger individually. You can do this as well. For example, the following Property Trigger will execute only if the Text property of the Textbox txtData is Hello, and the CheckBox myCheckBox is checked.

image

Better MVVM - Invoking Methods and Commands in your View Model and Passing Parameters

Have a look at the InvokeMethodAction and InvokeCommandAction (see the demo). There are some changes for these actions from Preview 1.

InvokeCommandAction lets you invoke a method against the View Model. Assume that you've a list box named userList - here is a simple example of how to execute a command whenever the selection is changed, and you can specify a parameter for your ICommand using the ActionParameter. In fact, you can pass more than one ActionParameter - and in that case, they will be passed as an object array to the CanExecute and Execute methods in your command.

image

And here is something more interesting - InvokeMethodAction. You can use InvokeMethodAction to invoke methods in your View Model directly. Assume that you have a UI with two text boxes and a button, and you've an Add method in your View Model that takes two arguments of type integer. This is what you need to do to invoke your Add method when the user clicks the button btnName.

image

ReactiveTrigger – Decoupling Triggers with the Help of MEF and System.Reactive

One interesting addition in this preview is the ReactiveTrigger. ReactiveTrigger lets you import an Observable you exported from somewhere else. This will let you create customized user input triggers pretty quickly. I'm not going to the implementation details, but assuming you are already a bit familiar with MEF concepts and System.Reactive concepts; here is what you can do (see the ReactiveTrigger demo in Slex.Lib.Demo for the entire source code).

Step 1 – Somewhere in your host application, create a Trigger and export it

Your exported method should match the signature Func<object,IObservable<EventResult>>. You can use the ObservableExport attribute in Slex.Lib to mark your Trigger as an exportable part. Also, the name you provide to the ExportName attribute will later be used in the XAML to 'import' this trigger.

image

Step 2 – In your application startup, call the Compose method in SlexPartComposer, and pass your catalogs

In this case, I'm simply passing an assembly catalog with the current assembly, because I've my Trigger as part of my host app. And, I've this line in the App.xaml.cs constructor.

image

Step 3 – Just use the trigger in your XAML

Here we go, you can import the exported trigger, and this will get fired whenever a key is pressed.

image

Using Slex with Blend

You should be able to use Blend to modify most Slex Triggers and Actions. For example, let us see how the above Event Trigger and the related action parameters will look like in Blend. You may find that you can modify the Conditions and Parameters of a Trigger from within Blend (well, they are AttachableCollections to be precise :)).

image

How Slex relates to the already available Behaviors, Triggers, and Actions that come with Expression Blend?

As mentioned earlier, Slex is built on top of the System.Windows.Interactions infrastructure, and you will be able to mix and match existing Expression Blend Behaviors, Triggers, and Actions along with Slex Triggers and Actions.

There are a few overlapping areas – for example, Slex has its own implementation for some Triggers like EventTrigger, that provides some 'extra' features when compared to Blend's EventTrigger.

What Next?

As already mentioned, this is a set of experimental hacks to bring some ideas forward. A few more ideas are in progress, and will be implemented going forward, when I've time.

If you are interested in co-hacking, drop me a mail at amazedsaint (at) gmail (dot) com.

Also, follow me on twitter @amazedsaint.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here