ARTICLE

Drag n Drop an element from one Panel to another in Silverlight 3

Posted by Paru Articles | C# Language August 01, 2009
In this article we see the code to drag and drop an element from one panel to another in Silverlight.
Reader Level:
Download Files:
 


In this application we see the code to drag and drop an element from one panel to another.

Here we use two Stack Panels. One is the containing panel and the other is the dropping panel.

img1.gif

There are four items in the lower panel. We can drag and drop or a single click can also move objects from one panel to the other.

Now let us see how the code can be:

XAML

In the designer we have

The Visual tree of control is as in the figure below. The scroll bar can be used as the requirements and number of items in the Item slider.

img2.gif

The code is:

<
Canvas x:Name="LayoutRoot" Background="White" Height="534" Margin="0,0,-200,0" 

VerticalAlignment="Top">
<Canvas x:Name="ContainedCanvas" Background="#FFC7F2F6" Height="476" Width="832" 
Canvas.Left="8" Canvas.Top="8">

<StackPanel x:Name="itemSlider" RenderTransformOrigin="0.5,0.5" Orientation="Horizontal" 

HorizontalAlignment="Left">

<StackPanel.RenderTransform>

      <TransformGroup>

            <ScaleTransform/>

            <SkewTransform/>

            <RotateTransform/>

            <TranslateTransform/>

      </TransformGroup>

</StackPanel.RenderTransform>

<Image Source="images/Creek.jpg" Stretch="Fill" x:Name="item2" HorizontalAlignment="Left"

 Tag="draggable" 
VerticalAlignment
="Top"d:LayoutOverrides="HorizontalMargin"/>

<Image HorizontalAlignment="Left" x:Name="item1" Source="images/Autumn-Leaves.jpg" Stretch="Fill" Tag="draggable" VerticalAlignment="Top"/>

<Image Source="Images/Desert-Landscape.jpg" Stretch="Fill" x:Name="item3" Margin="10,0,0,0"  

HorizontalAlignment="Left" Tag="draggable"VerticalAlignment="Top"/>

<Image Source="images/Forest-Flowers.jpg" Stretch="Fill" x:Name="item4" Margin="10,0,0,0"  

HorizontalAlignment="Left" Tag="draggable"VerticalAlignment="Top"/>

                             

                        </StackPanel>

     

<StackPanel x:Name="DragToStackPanel" HorizontalAlignment="Left" Background="#FFEED6D6"

 Height="300" Width="830" Orientation="Horizontal"/>

           

            </Canvas>

      </Canvas>

Now you have the look of the application.

Next is the real interesting part the code behind that makes the whole thing possible.

Note:  Please note that all the draggable controls are tagged as "draggable"

Code Behind

The methods to be noted in each event

Event  Method  Functionality  Return
MouseLeftButtonDown  CaptureMouse  Sets mouse capture to a System.Windows.UIElement. Returns true if the object has mouse capture; otherwise, returns false.
MouseMove  No specific method of the UI element related to this event but keeps track of the position of the mouse
MouseLeftButtonUp  ReleaseMouseCapture  Removes mouse capture from a System.Windows.UIElement. After this call, typically no object holds mouse capture. 

Now let us see each event in detail.

MouseLeftButtonDown

public
 void objFrameworkElement_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
            
//Start Drag
          
FrameworkElement objFrameworkElement = (FrameworkElement)sender;
            objFrameworkElement.CaptureMouse();
            
// Set the starting point for the drag
            StartingDragPoint = e.GetPosition(objFrameworkElement);
            
// Remove the element from it's control and move it to the parent
            
// if it's Tag contains the words [draggable]
            
if (objFrameworkElement.Tag.ToString().Contains("draggable"))
            {
               ContainingParent = objFrameworkElement.Parent 
as Panel;
               ContainingParent.Children.Remove(objFrameworkElement);
                
this.LayoutRoot.Children.Add(objFrameworkElement);
                UpdateElementPosition(objFrameworkElement, e.GetPosition(
this.LayoutRoot));
            }
            objFrameworkElement.MouseMove += 
new MouseEventHandler(objFrameworkElement_MouseMove);
            objFrameworkElement.MouseLeftButtonUp += 
new MouseButtonEventHandler(objFrameworkElement_MouseLeftButtonUp);
}

MouseMove

void
 objFrameworkElement_MouseMove(object sender, MouseEventArgs e)
        {
            
FrameworkElement objFrameworkElement = (FrameworkElement)sender;
            
Canvas objCanvas = (Canvas)objFrameworkElement.Parent;
            
Point Point = e.GetPosition(objCanvas);
            UpdateElementPosition(objFrameworkElement, Point);

        }

Update-element-position method

private
 void UpdateElementPosition(FrameworkElement objFrameworkElement, Point Point)
        {
            
Canvas.SetLeft(objFrameworkElement, Point.X - StartingDragPoint.X);
            
Canvas.SetTop(objFrameworkElement, Point.Y - StartingDragPoint.Y);        }

MouseLeftButtonUp

void
 objFrameworkElement_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            
//Stop Drag
            
FrameworkElement objFrameworkElement = (FrameworkElement)sender;
            objFrameworkElement.ReleaseMouseCapture();
                  objFrameworkElement.Width=300;
                        objFrameworkElement.Height=300;
            objFrameworkElement.MouseMove -=
                
new MouseEventHandler(objFrameworkElement_MouseMove);
            objFrameworkElement.MouseLeftButtonUp -=
                
new MouseButtonEventHandler(objFrameworkElement_MouseLeftButtonUp);
            
// If it is an element marked [draggable]
            
// try to drop it on a panel stored in the colPanels collection
            
if (objFrameworkElement.Tag.ToString().Contains("draggable"))
            {
                
if (ContainingParent == itemSlider)
                {
                    DraggedToParent = DragToStackPanel;
                    objFrameworkElement.Width = 300;
                    objFrameworkElement.Height = 300;
                }
                
else
                {
                    DraggedToParent = itemSlider;
                    objFrameworkElement.Width = 200;
                    objFrameworkElement.Height = 150;
                }
                
// Grab the position of the element being dragged in relation to it's position on the
               
// main canvas and it's position in relation to the panel it may be dropped on
                
Point mousePos1 = e.GetPosition(DraggedToParent);
                
Point mousePos2 = e.GetPosition(objFrameworkElement);
                
// Remove the element from the main canvas
                
this.LayoutRoot.Children.Remove(objFrameworkElement);
                DraggedToParent.Children.Add(objFrameworkElement);
                
Canvas.SetLeft(objFrameworkElement, mousePos1.X - mousePos2.X);
                
Canvas.SetTop(objFrameworkElement, mousePos1.Y - mousePos2.Y);
            }
        }

By implementing these we can achieve the dragging of a UI element into a different panel.

Happy Coding!

COMMENT USING