11 February 2011

A Blendable Windows Phone 7 / Silverlight clipping behavior

If you are moving images around on a Canvas, you don’t want to show them when they get, for example, a negative Y-coordinate – for else they move outside of the Canvas and over what is above that. I’ve seen numerous examples of clipping ‘utilities’ that basically all ape this article on The Code Project. For some reason no-one seems to have thought about making it a real behavior that can be used from Blend. So after a short discussion over Twitter and DM with Thomas Woo (aka @codechinchilla) I decide to do my own take.

It’s not exactly rocket science:

using System.Windows;
using System.Windows.Media;
using System.Windows.Interactivity;

namespace LocalJoost.Behavior
{
  public class ClipToBoundsBehavior: Behavior<FrameworkElement>
  {
    protected override void OnAttached()
    {
      base.OnAttached();
      AssociatedObject.SizeChanged += AssociatedObjectSizeChanged;
      AssociatedObject.Loaded += AssociatedObjectLoaded;
    }

    protected override void OnDetaching()
    {
      AssociatedObject.SizeChanged -= AssociatedObjectSizeChanged;
      AssociatedObject.Loaded -= AssociatedObjectLoaded;
      base.OnDetaching();
    }

    void AssociatedObjectLoaded(object sender, RoutedEventArgs e)
    {
      SetClip();
    }

    void AssociatedObjectSizeChanged(object sender, SizeChangedEventArgs e)
    {
      SetClip();
    }

    private void SetClip()
    {
      AssociatedObject.Clip = new RectangleGeometry
      {
        Rect = new Rect(0, 0, 
          AssociatedObject.ActualWidth, AssociatedObject.ActualHeight)
      };
    }
  }
}

…and it’s even less code than the original sample. Drag this thingie in Blend on your Canvas - or whatever other framework element whose children you want to display only within its bounds - and you’re done. Or your designer is done.

I made this for a little Windows Phone 7 App I am currently working on, but it will pretty much work in plain Silverlight, and I am pretty sure it will work on WPF (and thus Microsoft Surface) as well.

2 comments:

peSHIr said...

I can already tell I'm going to like using/writing Behaviors myself when I get round to it. Seem to be "blendable ExtensionControls" (WinForms) or extension method (C#) to me. I like the concept!

Don Fitzsimmons said...

I know you posted this years ago, but thank you. I was looking for a way to bind a line to canvas width and this worked perfectly.