Monday, September 13, 2010

Making any User Control Draggable in Silverlight

Silverlight gives you easy access to make your User Controls come alive. For example you can make any control in Silverlight draggable.  Here's how:
In your  XAML Code add a TranslateTransform inside your layout grid of your user control.  The TranslateTransform will allow you to move your grid along the x and y coordinates of your application
Listing 1 - Adding the TranslateTransform to your control
<Grid x:Name="LayoutRoot" >
       <Grid.RenderTransform>
           <TransformGroup>
               <ScaleTransform/>
               <SkewTransform/>
               <RotateTransform/>
               <TranslateTransform x:Name="LocalTranslateTransform"/>
           </TransformGroup>
       </Grid.RenderTransform>
Now we want to pick a control inside the UserControl to grab onto.  In our sample we will use a Border control.  Inside the Border control, we'll add mouse events to handle the various states of dragging with the mouse.
Listing 2 - Hooking up the mouse events to the Border control
<Border x:Name="myToolbar" MouseLeftButtonDown="OnToolbarClicked" MouseLeftButtonUp="OnToolbarReleased" MouseMove="OnToolbarMoving"  />
The Code
The XAML part was pretty simple.  Now let's look at the code behind.  All of the dragging functionality is handled by our 3 event handlers: OnToolbarClicked, OnToolbarReleased, and OnToolbarMoving.  When we first click down on the border control, we need to record the initial offset point for our transform.  We also need to set the state to mouseDownInToolbar to true to indicate we are dragging.  Finally we need to set the mouse mode to capturing inside the border control.
Listing 3 - Handling the mousedown event inside the border
private void OnToolbarClicked(object sender, MouseButtonEventArgs e)
{
   mouseDownInToolbar = true;
   DragOffset = e.GetPosition(LayoutRoot);
   toolbarBorder.CaptureMouse();
}
While the mouse is in the mouseDownInToolbar state, we need to translate the position of the toolbar in reference to the position of the mouse.  Listing 4 illustrates how we go about this.  We get the position of the mouse relative to the main grid of the control.  Then we change the TranslateTransform of the grid based on the new position of the mouse.  We also need to offset the current mouse position by the original location of the mouse when we first clicked down in the control.  Everytime we move the mouse, the new TranslateTransform will be computed and our control will move to the translated location.  The mouse cursor will remain at the point when we first clicked the toolbar.
Read more: C# Corner