thespot4sap.com independent sap information
 

get SAP Access - pay monthly

SAP Tutorials    Online SAP Training    SAP CBT's    Forums    SAP Articles    SAP Jobs    Resumes
  SAP Access    SAP Blogs    SAP Books     Links     Vendor Directory     Submit Content    Search
Previous posts in SAPscript
Page 4981 of 5524

Dragging WPF elements

Blogger : MSDN Blogs
All posts : All posts by MSDN Blogs
Category : SAPscript
Blogged date : 2006 Mar 03

This is the first in a series of post exploring that beloved UI gesture: dragging and dropping things around.

In this first post, I'll take a look at the simplest, most striaghtforward approach: adding a bunch of event handlers to your window and updating layout properties. I'll be using VB.NET - converting to C# should not be too difficult.

First, we'll start with this code in Window1.xaml.

 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="
http://schemas.microsoft.com/winfx/2006/xaml"
 Title="Drag Canvas" Height="300" Width="300">
 

 
  
    Drag Canvas Sample
   

     This sample demonstrates the easiest way to drag shapes (or any other
     elements) on a Canvas area.

  

 

 

  
   
    
     
     
    

   

  

       Width="32" Height="32" Fill="LightPink" />
       Width="40" Height="16" Fill="Tan" />
       Width="32" Height="62" Fill="Green" />
       Width="62" Height="62" Fill="Orange" />

 

 

This creates a simple window that looks like this.

OK, now let's roll up our sleeves and build this bit by bit by adding code to Window1.xaml.vb.

First off, we'll start with some fields in Window1. Right under the constructor, we can add this bit of code.

Private m_StartPoint As Point ' Where did the mouse start off from?
Private m_OriginalLeft As Double ' What was the element's original x offset?
Private m_OriginalTop As Double ' What was the element's original y offset?
Private m_IsDown As Boolean ' Is the mouse down right now?
Private m_IsDragging As Boolean ' Are we actually dragging the shape around?
Private m_OriginalElement As UIElement ' What is it that we're dragging?
Private m_OverlayElement As Rectangle ' What is it that we're using to show where the shape will end up?

This is all information that we'll track while moving the shapes in the Canvas about.

Now, let's write the code to start the dragging. When the mouse goes down, we'll capture a some of the information we'll use, and then when the user begins to move the mouse, we'll add an element to show where the content will end up.

Private Sub MyCanvas_PreviewMouseLeftButtonDown(ByVal sender As Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles MyCanvas.PreviewMouseLeftButtonDown
 If MyCanvas Is e.Source Then
  Exit Sub
 End If

 m_IsDown = True
 m_StartPoint = e.GetPosition(MyCanvas)
 m_OriginalElement = e.Source
 MyCanvas.CaptureMouse()
 e.Handled = True
End Sub

Private Sub MyCanvas_PreviewMouseMove(ByVal sender As Object, ByVal e As System.Windows.Input.MouseEventArgs) Handles MyCanvas.PreviewMouseMove
 If m_IsDown Then
  If Not m_IsDragging AndAlso _
   Math.Abs(e.GetPosition(MyCanvas).X - m_StartPoint.X) > SystemParameters.MinimumHorizontalDragDistance AndAlso _
   Math.Abs(e.GetPosition(MyCanvas).Y - m_StartPoint.Y) > SystemParameters.MinimumVerticalDragDistance Then
   DragStarted()
  End If
  If m_IsDragging Then
   DragMoved()
  End If
 End If
End Sub

A few things to note are the fact that we capture the mouse when it goes down (in case the user moves the mouse out of the bounding area), and the DragStarted() and DragMoved() helper methods I'm using. Also, notice how we use the system paramters to respect the user's selection for how far the mouse needs to move before we start dragging. This is especially helpful for laptops and tablets, on which it's very common to have the pointer shake a bit when working with the mouse stick thingy or a pen.

Now, what is it that we do in our helper methods?

Private Sub DragStarted()
 m_IsDragging = True

 m_OriginalLeft = Canvas.GetLeft(m_OriginalElement)
 m_OriginalTop = Canvas.GetTop(m_OriginalElement)

 ' Add a rectangle to indicate where we'll end up.
 ' We'll just use an alpha-blended visual brush.
 Dim brush As VisualBrush
 brush = New VisualBrush(m_OriginalElement)
 brush.Opacity = 0.5

 m_OverlayElement = New Rectangle()
 m_OverlayElement.Width = m_OriginalElement.RenderSize.Width
 m_OverlayElement.Height = m_OriginalElement.RenderSize.Height
 m_OverlayElement.Fill = brush

 MyCanvas.Children.Add(m_OverlayElement)
End Sub

Private Sub DragMoved()
 Dim currentPosition As Point = System.Windows.Input.Mouse.GetPosition(MyCanvas)
 Dim elementLeft As Double = (currentPosition.X - m_StartPoint.X) + m_OriginalLeft
 Dim elementTop As Double = (currentPosition.Y - m_StartPoint.Y) + m_OriginalTop
 Canvas.SetLeft(m_OverlayElement, elementLeft)
 Canvas.SetTop(m_OverlayElement, elementTop)
End Sub

Notice how I use a alpa-blended VisualBrush to show the user where the shape is going to end up. Also, because I'm working with a Canvas, I simply change the Left and Top attached properties. If this were a DockPanel, I might try seeing whether I would want to try snapping to an edge; or if this were a Grid, I might try to figure out in which cell the shape would drop. I'm just sticking to the simplest case in this sample, but you can take it as far as you want.

This is all well and good, but how do we actually drop the shape? Two typical gestures are releasing the mouse button, or pressing Escape (to cancel the operation). Let's code that up.

Private Sub MyCanvas_PreviewMouseLeftButtonUp(ByVal sender As Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles MyCanvas.PreviewMouseLeftButtonUp
 If m_IsDown Then
  DragFinished(False)
  e.Handled = True
 End If
End Sub

Private Sub Window1_PreviewKeyDown(ByVal sender As Object, ByVal e As System.Windows.Input.KeyEventArgs) Handles Me.PreviewKeyDown
 ' This is handled at the window level, because neither MyCanvas nor
 ' its children ever get keyboard focus.
 If e.Key = Input.Key.Escape AndAlso m_IsDragging Then
  DragFinished(True)
 End If
End Sub

Again, a helper method to make it easy to isolate what happens when we actually finish dragging, and here's the implementation for it.

Private Sub DragFinished(ByVal canceled As Boolean)
 System.Windows.Input.Mouse.Capture(Nothing)
 If m_IsDragging Then
  MyCanvas.Children.Remove(m_OverlayElement)
  If Not canceled Then
   Canvas.SetLeft(m_OriginalElement, Canvas.GetLeft(m_OverlayElement))
   Canvas.SetTop(m_OriginalElement, Canvas.GetTop(m_OverlayElement))
  End If
  m_OverlayElement = Nothing
 End If
 m_IsDragging = False
 m_IsDown = False
End Sub

And that, my dear readers, completes today's sample. Give it try, play around with it, marvel at the alpha-blended 'preview', and try extending it. Can you add other controls to drag around?


This posting is provided "AS IS" with no warranties, and confers no rights. Use of included script samples are subject to the terms specified at http://www.microsoft.com/info/cpyright.htm.


Read comments or post a reply to : Dragging WPF elements
Page 4981 of 5524

Newest posts
New Page 1

 

 

About Us   Contact Us   Privacy   Disclaimer   Feedback   Email Discussion   Newsletter  

Copyright © - Independent SAP Information
Learn XML, Guesthouses and B&B's