Saturday, February 6, 2010

Tips for Developing Silverlight Behaviors

Silverlight behaviors are classes that derive from Behavior<T> defined in System.Windows.Interactivity. They are used to add functionality to controls in XAML. When the XAML is being processed the behaviors that are contained in a control, say a TextBox, are instantiated and the OnAttached method is called. When the control is being destroyed the OnDetaching gets called.

Tip 1 – Connect and disconnect events

I have a small code pattern I use to avoid memory leaks caused by behaviors. I always create two methods on the behavior named ConnectToEventHandlers and DisconnectFromEventHandlers and I keep them toguether in source code. Naturally they are called on OnAttached and OnDetaching. But the real tip here is if you keep both toguether you can easily check if there is ‘+=’ and a ‘–=’ pair for each event you are observing.

   1: /// <summary>
   2: /// Called after the behavior is attached to an AssociatedObject.
   3: /// </summary>
   4: /// <remarks>Override this to hook up functionality to the AssociatedObject.</remarks>
   5: protected override void OnAttached()
   6: {            
   7:     base.OnAttached();
   8:     this.ConnectToEventHandlers();
   9:     this.Enabled = true;
  10: }
  11:  
  12: /// <summary>
  13: /// Called when the behavior is being detached from its AssociatedObject, but before it has actually occurred.
  14: /// </summary>
  15: /// <remarks>Override this to unhook functionality from the AssociatedObject.</remarks>
  16: protected override void OnDetaching()
  17: {
  18:     this.Enabled = false;
  19:     this.DisconnectFromEventHandlers();
  20:     base.OnDetaching();
  21: }
  22:  
  23: #endregion
  24:  
  25: #region Event Connecting and Disconnection
  26:  
  27: private void ConnectToEventHandlers()
  28: {
  29:     this.AssociatedObject.LostFocus += new RoutedEventHandler(AssociatedObject_LostFocus);
  30:     this.AssociatedObject.KeyDown += new KeyEventHandler(AssociatedObject_KeyDown);
  31: }
  32:  
  33: private void DisconnectFromEventHandlers()
  34: {
  35:     this.AssociatedObject.LostFocus -= new RoutedEventHandler(AssociatedObject_LostFocus);
  36:     this.AssociatedObject.KeyDown -= new KeyEventHandler(AssociatedObject_KeyDown);
  37: }
  38:  
  39: #endregion

No comments: