Drag and Drop in Silverlight

August 16, 2008 14:19 by wjchristenson2

In this example, I am going to show you how to drag and drop objects in a Silverlight Application.  To make it a little more fun, we are going to be dragging ducks around a Duck Hunt for NES canvas.  Bring back the memories?  The following code snippet is our XAML document that gives us 2 ducks on our page.

 

   1:  <UserControl x:Class="Drag_N_Drop.Page"
   2:      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
   3:      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
   4:      xmlns:local="clr-namespace:Drag_N_Drop"
   5:      Width="500" Height="438">
   6:      <Canvas x:Name="LayoutRoot">
   7:          <Canvas.Background>
   8:              <ImageBrush ImageSource="Images/canvas.png" />
   9:          </Canvas.Background>
  10:          
  11:          <local:Duck Canvas.Left="140" Canvas.Top="20" />
  12:          <local:Duck Canvas.Left="240" Canvas.Top="20" />
  13:      </Canvas>
  14:  </UserControl>

So we have 2 ducks on a canvas.  The next step is to wire each duck up so that when the user drags a duck across the screen, the duck moves with the cursor until they let go.  First we define our variables.  We need a variable to hold the X and Y coordinates of the mouse when we begin dragging and another variable to track if the user has their left mouse button down or not.

 

   1:  Private isMouseDown As Boolean = False
   2:  Private mousePosition As Point = Nothing

We want to handle 3 mouse events for each duck: MouseLeftButtonDown, MouseMove, and MouseLeftButtonUp.  When the page is loaded, I loop through through each duck on the canvas and add these 3 event handlers for them.

 

   1:      Private Sub Page_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
   2:          Me.InitializeComponent()
   3:   
   4:          For Each element As UIElement In LayoutRoot.Children
   5:              If TypeOf (element) Is Duck Then
   6:                  Dim item As Duck = DirectCast(element, Duck)
   7:                  AddHandler item.MouseLeftButtonDown, AddressOf duck_MouseLeftButtonDown
   8:                  AddHandler item.MouseLeftButtonUp, AddressOf duck_MouseLeftButtonUp
   9:                  AddHandler item.MouseMove, AddressOf duck_MouseMove
  10:              End If
  11:          Next
  12:      End Sub

When the user presses the left mouse button on a duck, we need to capture what the current X and Y coordinates are, set that the mouse left button is down, and capture the mouse events for the duck.

 

   1:      Sub duck_MouseLeftButtonDown(ByVal sender As Object, ByVal e As MouseEventArgs)
   2:          Dim item As Duck = DirectCast(sender, Duck)
   3:          mousePosition = e.GetPosition(Nothing)
   4:          Me.isMouseDown = True
   5:          item.CaptureMouse()
   6:      End Sub

Take note of line 5.  The item.CaptureMouse() method basically tells Silverlight to only handle mouse events for the duck we are dragging.  As the user moves the mouse, the MouseMove event is fired.  This event will fire regardless if the user is dragging the duck or not.  Therefore we check to see if the left mouse button is down first.  If it is, it's being dragged so we want to refresh the duck's new position.  We use the current position of the mouse and calculate what the new position the duck should be set to relative to the canvas.


   1:      Sub duck_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)
   2:          Dim item As Duck = DirectCast(sender, Duck)
   3:   
   4:          If (Me.isMouseDown) Then
   5:              Dim deltaV As Double = e.GetPosition(Nothing).Y - mousePosition.Y
   6:              Dim deltaH As Double = e.GetPosition(Nothing).X - mousePosition.X
   7:              Dim newTop As Double = deltaV + DirectCast(item.GetValue(Canvas.TopProperty), Double)
   8:              Dim newLeft As Double = deltaH + DirectCast(item.GetValue(Canvas.LeftProperty), Double)
   9:              item.SetValue(Canvas.TopProperty, newTop)
  10:              item.SetValue(Canvas.LeftProperty, newLeft)
  11:              mousePosition = e.GetPosition(Nothing)
  12:          End If
  13:      End Sub

When the user releases the left mouse button, we release the mouse capture and set our isMouseDown variable back to false.

 

   1:      Sub duck_MouseLeftButtonUp(ByVal sender As Object, ByVal e As MouseEventArgs)
   2:          Dim item As Duck = DirectCast(sender, Duck)
   3:          isMouseDown = False
   4:          mousePosition = New Point(0, 0)
   5:          item.ReleaseMouseCapture()
   6:      End Sub


The final application looks like below.  You can drag the ducks around the canvas.

Drag-N-Drop_Soln.zip (2.11 mb)


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Comments