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 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 InvokingCondition
s 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):
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.
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.
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
.
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.
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 AttachableCollection
s 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 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.