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:
- Introduction to Behaviors and Triggers
- 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:
Triggers in Slex, and Actions inside them, can be invoked based on conditions:
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
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
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
myStoryBoard, and your
chkMain, this is something that you can do (see the StoryBoardAction demo):
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
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
txtData is Hello, and the
myCheckBox is checked.
Better MVVM - Invoking Methods and Commands in your View Model and Passing Parameters
Have a look at the
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
Execute methods in your command.
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
ReactiveTrigger – Decoupling Triggers with the Help of MEF and System.Reactive
One interesting addition in this preview is the
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.
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.
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.
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 ).
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
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.