Behaviors : Writing Your Own Triggers

April 9th, 2009     |     View Comments

In my previous posts, I briefly discussed what behaviors are and how to use them. Let’s now talk about writing your own behaviors. Behaviors is a catch-all word that describes behaviors, actions, and extensible triggers. For an overview of what all three mean, check out Jeff Kelly’s blog post as well as Christian Schormann’s two overview blog posts on this topic.

Because there is already some great material out there on the basics of behaviors, I am going to shift gears and explain how to write behaviors. First up, I am going to go into some detail in this blog post by showing you how to write your own Trigger!

What are Triggers?
Like I mentioned earlier, behaviors (much like a famed group of musketeers!) are made up of three components – the Behavior, the Action, and the Trigger. The Trigger is really the catalyst for causing an Action and indirectly a Behavior to actually do something.

Examples of triggers range from something common such as an EventTrigger that fires an Action when a mouse or keyboard event is raised to something fun like a CollisionTrigger that fires an Action when two objects collide with each other. The thing to note is that, much like everything in our implementation of behaviors, Triggers are extensible. You can easily create your own kind of crazy triggers…such as what I am going to show you next.

The DoubleClick Trigger
One common gesture that I miss in Silverlight is the ability to double click. You can always click once, but if I want an Action to do something with a double click, I will have to provide this functionality myself. The below code shows you what a sample double click implementation looks like:

namespace TriggerTest
{
public class DoubleClickTrigger : TriggerBase<UIElement>
{
private int count = 0;
private DispatcherTimer _timer;
 
public int DoubleClickSpeed
{
get { return (int)GetValue(DoubleClickSpeedProperty); }
set { SetValue(DoubleClickSpeedProperty, value); }
}
 
public static readonly DependencyProperty DoubleClickSpeedProperty = DependencyProperty.Register("DoubleClickSpeed", typeof(int), typeof(DoubleClickTrigger), new PropertyMetadata(500, DoubleClickSpeedChanged));
 
private static void DoubleClickSpeedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
// Code for dealing with your property changes
}
 
protected override void OnAttached()
{
base.OnAttached();
 
this.AssociatedObject.MouseLeftButtonDown += new MouseButtonEventHandler(AssociatedObject_MouseLeftButtonDown);
}
 
void AssociatedObject_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (count == 0)
{
_timer = new DispatcherTimer();
_timer.Interval = new TimeSpan(0, 0, 0, 0, DoubleClickSpeed);
_timer.Tick += new EventHandler(ResetCount);
_timer.Start();
}
 
count++;
 
if (count >= 2)
{
this.InvokeActions(null);
}
}
 
void ResetCount(object sender, EventArgs e)
{
count = 0;
_timer.Stop();
}
 
protected override void OnDetaching()
{
base.OnDetaching();
 
this.AssociatedObject.MouseLeftButtonDown -= new MouseButtonEventHandler(AssociatedObject_MouseLeftButtonDown);
}
}

When this trigger is used on an Action, double clicking on the element your Action is listening to will cause it to fire. I have a property called DoubleClickSpeed that allows you to adjust how quick or slow the double click needs to be before your two clicks are registered as a double click.

Looking Briefly at the Code
While it seems like a lot of code, what I am doing is actually pretty straightforward. Instead, I am going to remove all of the double click specific functionality and just show you the bare minimum of what you need to create a trigger:

public class Trigger1 : TriggerBase<DependencyObject>
{
protected override void OnAttached()
{
base.OnAttached();
}
 
protected override void OnDetaching()
{
base.OnDetaching();
}
 
//
// To invoke any associated Actions when this Trigger gets called, use
// this.InvokeActions(o)
//
}

Notice that I am extending my class from TriggerBase – a type that is provided for you inside Microsoft.Expression.Interactivity.dll. Once I extend from the TriggerBase class, all I really have left to do is just override the OnAttached and OnDetaching methods like I show above.

Think of your OnAttached and OnDetaching methods like the constructor and destructor of your class. Anything you want initialized when the Trigger gets associated with an Action, be sure to specify it in the OnAttached method. Anything you want removed or cleaned up when the Trigger is no longer being associated with anything, be sure to put that in your OnDetaching method.

Finally, to actually have your trigger fire, though, you need to make a call to the InvokeActions method. Only when InvokeActions gets called will any Actions associated with this Trigger be notified to do whatever it is they do. My DoubleClickTrigger is simply an extension of the few lines of code that make up a barebones trigger starting point.

Using Triggers in Blend
Once you have written your trigger, using them in your own project is pretty straightforward. Draw a simple element, such as a rectangle, and drag and drop an Action on to it. If you don’t have any Actions you can use, feel free to borrow some from your peers on the Expression Gallery’s Behaviors category.

When you apply an Action to an element and select it, your Properties Inspector will display the current trigger applied as well as any properties your Action may expose. You can click the New button inside the Triggers category to display a dialog that allows you to pick your DoubleClickTrigger:

trigger_editor

Once you have selected your DoubleClickTrigger, click OK to accept it as the Trigger for your Action. After you do that, your Trigger category will display the things relevant to you customizing your DoubleClickTrigger:

Trigger_DoubleClick

Well, that is all there is to it. Hopefully this post gave you a quick overview of how to write your own Triggers for this extensible family we call Behaviors.

Update: Thanks to a comment from Bart, I made a simple change to the code.

Cheers!
Kirupa :)

View Comments to “Behaviors : Writing Your Own Triggers”

  1. Bart Czernicki Says:

    Nice article.

    The code is not thread-safe here. Don’t mean to be a “threading troll”, but in this case you actually might have a problem as your reset method/increment could step over each other.

    It wouldn’t break anything but probably the double click wouldn’t register or fire early. Maybe changing the line:

    if (count == 2)
    to
    if (count >= 2)

    this way if for some reason the Reset reset one click and not the previous then it wouldn’t seem to act weird and fire off on one click.

  2. kirupa Says:

    Hi Bart – thanks a lot for the feedback. I have updated the post with your change.

    Cheers!
    Kirupa

  3. Edgar Says:

    Wouldn’t it be simpler to just store off the time of the previous click instead of using a DispatchTimer? So the code would look something like this:
    DateTime _lastClickTime = DateTime.Min;
    void AssociatedObject_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
    TimeSpan timeSinceLastClick = DateTime.Now – _lastClickTime;
    if (timeSinceLastClick <= DoubleClickSpeed)
    {
    this.InvokeActions(null);
    }
    }

    Also correct me if I’m wrong but I wouldn’t think Thread Safety would be an issue, because the Trigger should always run on the UI Thread.

  4. kirupa Says:

    Edgar – I changed it to use the timestamp approach shortly after I published my original one.

    I agree that it is much simpler!

    :)

  5. kelly Says:

    Help!

    Hello is anyone here who kan help me?. Im having problems in linking my gallery made in flash to the rest of my homepage made in html…I have seen several examples of codes, about how to link from flash to a new URL, but I just need to link to a local html file…

    So I have to questions.

    First. Which are the codes to use in my flash buttom to link to a local html file, or another flash file?

    And second.How relevant is the swf location?. I mean, I named my gallery: “galeria.html”(I have published my flash gallery in html). Does the swf file have to stay in the same directory than the gallery in order to kan display it in the browser?

    Thanks a lot to whom take some time to read this.

    And sorry if there is any spelling error. This is the first time I write some english, in many many years.

    Regards,

    Kelly

  6. Rick Says:

    Hello,
    I am trying to write a custom behavior using SL3 and Blend3 but I am not getting very far.

    public class DoubleClickTrigger : TriggerBase
    {

    }

    Error:

    error CS0308: The non-generic type ‘System.Windows.TriggerBase’ cannot be used with type arguments

    I have referenced Microsoft.Expression.Interactions.dll but cannot find the Microsoft.Expression.Interactivity.dll mentioned in most samples. I suspect the final version of SL3 and/or Blend3 have changed things up a bit.

    Any ideas?

    Thanks,

    Rick

  7. kirupa Says:

    Rick – please add a reference to System.Windows.Interactivity instead. The samples and other documentation are out of date because we changed the assembly name before we released :)

    Cheers!
    Kirupa

  8. Jogo Says:

    Thanks google to you, I found this site.

  9. Bri Says:

    okay so i found a flash tutorial for flash mx 2004 called liquify image effect and it has horrible directions for teens doing projects in school i suggest you fix that cuz i’m not happy

  10. Amrinder Singh Says:

    nice post….

  11. William Wachter Says:

    I know this if off topic but I’m looking into starting my own blog and was curious what all is required to get setup? I’m assuming having a blog like yours would cost a pretty penny? I’m not very internet savvy so I’m not 100% sure. Any recommendations or advice would be greatly appreciated. Thank you

  12. Serena Says:

    A behavior is something you attach to an element, modifying the way in which the element should present itself, or how the element should respond to user interactions. First, Let us add an existing behavior to an object to see how behaviors work. Later we’ll create a custom behavior and may use the same from Blend.A Trigger can invoke a set of Actions, when it is fired. For example, you can nest few actions (like PropertyChangeAction to change a property of an element) in an EventTrigger, so that those actions will get executed when a specific Event occurs. You can attach more than one trigger to an element.
    If you have some WPF background, you may quickly remember the DataTriggers, MultiDataTriggers, etc.There are various Triggers and Actions that comes ‘out of the box

  13. buy cheap music Says:

    http://www.cheapmusicsites.com
    Great article! I really love the second paragraph, I know exactly what you mean! This site is great thanks again!

  14. acne free in 3 days Says:

    I used to be on the lookout for crucial info on this subject. The information was necessary as I am about to launch my own portal. Thanks for providing a lacking hyperlink in my business. Anyway, in my language, there are not much good supply like this.

  15. link wheel Says:

    I have really enjoyed flipping through your blog! It made me realize I have too many projects on the go BUT there is hope.

  16. south beach diet recipes Says:

    Incredible post! This could help numerous people discover out about this matter. Do you wish to incorporate video clips along with these? It could undoubtedly assist out. Your cause was spot on and owing to you; I in all probability won’t have to describe all the things to my pals. I can merely direct them here. Anyway, in my language, there are usually not a lot good supply like this.

  17. dich vu seo Says:

    Glorious read, I just passed this onto a colleague who was doing a little analysis on that. And he actually purchased me lunch because I found it for him smile So let me rephrase that: Thanks for lunch! Anyway, in my language, there usually are not much good source like this.

  18. jordan retros Says:

    These youthfuljordan retros adult females share a frequentjordan fusions attribute: red gown, aged 25 years or more youthful. Nearby temporary panic, younger gals didn’t dare to go out sporting a red jacket.

  19. guest Says:

    thanks dude plz set this in pdf to download

  20. rss feed Says:

    Unbelievable rss feed submit! This could rss feed support a number of individuals rss feed find out about this matter. Do you need to incorporate video clips along with these? It rss feed could undoubtedly help out. rss feed Your purpose was spot on and owing to you; I most likely won’t have to explain all the pieces to my pals. I rss feed can merely direct them here. Anyway, in my language, there will not be a lot good source like this.

  21. Foram Savant Says:

    Hi, I would to tell you that I have found this post to be super helpful to me. I also have a simple request for you, would it be Ok if I were to send a couple of my own great posts for other subscribers to view. Please get back to me, regards Jake

  22. Mario Leyva Says:

    I used to be more than happy to find this internet-site.I wished to thanks to your time for this excellent read!! I definitely enjoying each little little bit of it and I’ve you bookmarked to take a look at new stuff you blog post.

  23. Ordering Steroids Says:

    32. You could definitely see your enthusiasm in the work you write. The world hopes for even more passionate writers like you who aren’t afraid to mention how they believe. All the time follow your heart.

  24. Garth Vrbas Says:

    Do you have a spam issue on this website; I also am a blogger, and I was curious about your situation; we have created some nice practices and we are looking to swap techniques with other folks, be sure to shoot me an email if interested.

  25. 铝材切割机 Says:

    Do you mind if I quote a few of your posts as long as I provide credit and sources back to your blog? My blog is in the exact same area of interest as yours and my visitors would truly benefit from some of the information you provide here. Please let me know if this alright with you. Thank you!

  26. Anonymous Says:

    The code is not thread safe here. I do not want to be a “troll threading”, but then you really have a problem as the method of reset / growth can override the other. Testking 642-447

  27. Anonymous Says:

    The code is not thread safe here. I do not want to be a “troll threading”, but then you really have a problem as the method of reset / growth can override the other. Testking 642-447

  28. Certskey Says:

    The code is not thread safe here. I do not want to be a “troll threading”, but then you really have a problem as the method of reset / growth can override the other. Testking 642-447

  29. phonglan Says:

    ÿþL

  30. aassddaag Says:

    My wife and i felt really fulfilled when Raymond managed to conclude his basic research from your ideas he got through the weblog. It is now and again perplexing just to be giving for free guides that many people today have been selling. And now we understand we now have the writer to appreciate for this. The most important illustrations you made, the easy website menu, the friendships you make it possible to engender – it’s most astonishing, and it is aiding our son and us recognize that the concept is interesting, and that is exceptionally vital. Many thanks for everything!

  31. may loc nuoc Says:

    ejected sleeper databank  from the  terminal lance  ending the  transaction realty   don’t ask don’t tell  forget to take your card with you! Please don’t idle your  vehicle!.This   is was a preposition  my may loc nuoc

  32. Best Magento Themes Says:

    This is a great help. I can now add features to my http://magentothemes101.com/ to be more exquisite. Thanks Man!!!

  33. Anonymous Says:

    thank you okay so i found a flash tutorial for flash mx 2004 called liquify image effect and it has horrible directions for teens doing projects in school i suggest you fix that cuz i’m not happypornoporno am trying to write a custom behavior using SL3 and Blend3 but I am not getting very far.

  34. pan card Says:

    Good blog! I really love how it’s easy on my eyes as well as the data are well written. I am wondering how I could be notified whenever a new post has been made. I have subscribed to your rss feed which should do the trick! Have a nice day!

  35. Football Helmet Visors Says:

    Gawd, I just came from the Boston Globe web site: the comments sections there are just chock-loaded with maliciously gleeful (and needless to mention, badly confused) right wing commentators. I have to say what while you right wingers may not know much about math, science, economics, history, current events, and such, you do know how to rapidly fill up a comments section, even ones belonging to allegedly liberal newspapers, with rubbish.

  36. » Self-Assembling Robotic Cubes Can Replicate Objects Says:

    [...] very frequent basis. The view is set to "news". Try clicking on "video" and "2" for more articles. M.I.T. researchers experiment with modular bots smart enough to morph into things placed near them …te and to share power, the cubes use "electropermanent magnets," materials whose magnetism [...]

  37. דירות למכירה בפתח תקווה Says:

    שלום לכולכם דבר ראשון בשם כולם אני צריך לכתוב שחיברת מימרה נהדר . ברצוני לשתף אותכם , אתמול הייתי בחברת תיווך אמינה ביותר , אילואם הינכם מחפשים דירות למכירה בהוד השרון בארץ ישראל תבואו לחברת תיווך רומן נדלן , הם יגלו עבורכם את הבית הטוב מאוד , כי קיים להם מקצוענות נכבד ומאגר דירות גדול .בקיצור עדיף מאוד .

Leave a Reply

blog comments powered by Disqus