/ Published in: C#
Expand |
Embed | Plain Text
Copy this code and paste it in your HTML
// WPF Canvas Object // Canvas LayoutCanvas; // // Events Required // // Canvas_PreviewMouseLeftButtonDown // Canvas_PreviewMouseMove // Canvas_PreviewMouseLeftButtonUp // Parent_PreviewKeyDown // // LayoutCanvas.PreviewMouseLeftButtonDown += LayoutCanvas_PreviewMouseLeftButtonDown; // LayoutCanvas.PreviewMouseMove += LayoutCanvas_PreviewMouseMove; // LayoutCanvas.PreviewMouseLeftButtonUp += LayoutCanvas_PreviewMouseLeftButtonUp; // WindowOrPage.PreviewKeyDown += WindowOrPage_PreviewKeyDown; // // Parameters Required // // For capturing the mouse position: // Point ddStartPoint; // // The top left corner of the child object (left = x, top = y) // double ddOriginalLeft; // double ddOriginalTop; // // Properties for managing the state of the drag & drop process: // bool ddIsMouseDown; // bool ddIsBeingDragged; // // Our original UI element (in my case the children are all Image objects) // UIElement ddOriginalElement; // // The container of the above element when we are in dragging mode // System.Windows.Shapes.Rectangle ddOverlay; // // // Canvas_PreviewMouseLeftButtonDown // // We assign this to our Canvas object as it will control // catching whether or not we are clicking on the canvas itself // or on one of its children // private void LayoutCanvas_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { // If the source of the click is our canvas object then we want // to exit because we are looking for it's children to drag // and not the canvas itself. if(e.Source == LayoutCanvas) { return; } // Identifies that we have started dragging ddIsMouseDown = true; // Captures the mouse position in the layout canvas ddStartPoint = e.GetPosition(LayoutCanvas); // Sets up our element that we will be dragging ddOriginalElement = (UIElement)e.Source; // Tells the Window to give the mouse to the LayoutCanvas // object. LayoutCanvas.CaptureMouse(); e.Handled = true; } // // Canvas_PreviewMouseMove // // Our event handler for updating the position of our // dragged element // // This introduces two helper methods DragStarted() and DragMoved() // They will be covered later on in the code. // private void LayoutCanvas_PreviewMouseMove(object sender, System.Windows.Input.MouseEventArgs e) { if(ddIsMouseDown) { if(!ddIsBeingDragged) { // Capture our mouse position relative to the LayoutCanvas object var mousePosition = e.GetPosition(LayoutCanvas); // Creates a transparent rectangle around our current drag point and we want to // check here that we are within that rectangle if(Math.Abs(mousePosition.X - ddStartPoint.X) > SystemParameters.MinimumHorizontalDragDistance && Math.Abs(mousePosition.Y - ddStartPoint.Y) > SystemParameters.MinimumVeritcalDragDistance) { DragStarted(); } } else { DragMoved(); } } } // // Canvas_PreviewMouseLeftButtonUp // // Controls the functionality for finishing our drag and drop process. // This will also introduce the call to DragFinished(bool state); // private void LayoutCanvas_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) { // This is a fairly simple check. If we are still dragging // or starting to drag which means ddIsMouseDown would be 'True' // then we don't stop the drag if(ddIsMouseDown) { DragFinished(false); } } // // Page_PreviewKeydown // // In my code I have my canvas in a Page, you can do this with a Window object as well. // private void Page_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e) { if(e.Key == Key.Escape && ddIsBeingDragged) { DragFinished = true; } } // Helper Methods // // DragStarted() // // private void DragStarted() { // Capture our last remaining properties // needed to support our drag and drop // process ddIsBeingDragged = true; ddOriginalLeft = Canvas.GetLeft(ddOriginalElement); ddOriginalTop = Canvas.GetTop(ddOriginalElement); // What we are doing here is creating a semi-transparent // mirror image of the object we are dragging. // // This allows us to visually see that we have selected // an object and are dragging it. brush.Opacity = 0.5; ddOverlay.Width = ddOriginalElement.RenderSize.Width; ddOverlay.Height = ddOriginalElement.RenderSize.Height; ddOverlay.Fill = brush; // Finally add the overlay to the LayoutCanvas for displaying LayoutCanvas.Children.Add(ddOverlay); } // // DragMoved(); // private void DragMoved() { // Capture the current mouse position, this will be used // to redraw the overlay element we created in DragStarted() var currentPosition = System.Windows.Input.Mouse.GetPosition(LayoutCanvas); var elementLeft = (currentPosition.X - ddStartPoint.X) + ddOriginalLeft; var elementTop = (currentPosition.Y - ddStartPoint.Y) + ddOriginalTop; // We update the overlay's position on the LayoutCanvas // by setting it's top left corner position below Canvas.SetLeft(ddOverlay, elementLeft); Canvas.SetTop(ddOverlay, elementTop); } // // DragFinished(); // private void DragFinished(bool canceled) { if(ddOverlay != null) { // capture our current position var topLeft = Canvas.GetLeft(ddOverlay); var top = Canvas.GetTop(ddOverlay); if(ddIsBeingDragged) { LayoutCanvas.Children.Remove(ddOverlay); // If it wasn't prematurely canceled, then // move the element to the current mouse position if(!canceled) { Canvas.SetLeft(ddOriginalElement, topLeft); Canvas.SetTop(ddOriginalElement, top); } // Release the mouse from the layoutcanvas. // This is very important. If you do not release the mouse // you have to set the focus of the mouse to another application // and then back again to regain mouse control LayoutCanvas.ReleaseMouseCapture(); // Reset our drag & drop properties ddOverlay = null; ddIsMouseBeingDragged = false; ddIsMouseDown = false; } } }