Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

WPF: How to drag a label within a custom canvas control

Status
Not open for further replies.

adrianjohnson

Programmer
May 16, 2002
145
GB
Hello,

I've got a Window which has a treeview in the left column and a canvas control in the main area. The canvas control is based on the custom control from the WPF Recipes in C# 2008 book published by Apress.

I've managed to get the drag and drop to work to a standard canvas control, but not to the new custom one. The custom control is within a class and referenced from the project.

DragCanvasControl class:

Code:
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Input; 
 
namespace LabWPFLayout2 
{ 
    public class DragCanvasControl : Canvas 
    { 
        private Point startPoint; 
        private Point selectedElementOrigins; 
        private bool isDragging; 
        private UIElement selectedElement; 
 
        static DragCanvasControl() 
        { 
            DefaultStyleKeyProperty.OverrideMetadata(typeof(DragCanvasControl), new FrameworkPropertyMetadata(typeof(DragCanvasControl))); 
        } 
 
        protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e) 
        { 
            base.OnPreviewMouseLeftButtonDown(e); 
 
            if (e.Source != this) 
            { 
                if (!isDragging) 
                { 
                    startPoint = e.GetPosition(this); 
                    selectedElement = e.Source as UIElement; 
                    this.CaptureMouse(); 
 
                    isDragging = true; 
 
                    selectedElementOrigins = new Point(Canvas.GetLeft(selectedElement), Canvas.GetTop(selectedElement)); 
                } 
                e.Handled = true; 
            } 
        } 
 
        protected override void OnPreviewMouseLeftButtonUp(MouseButtonEventArgs e) 
        { 
            base.OnPreviewMouseLeftButtonUp(e); 
 
            if (this.IsMouseCaptured) 
            { 
                isDragging = false; 
                this.ReleaseMouseCapture(); 
 
                e.Handled = true; 
            } 
        } 
 
        protected override void OnPreviewMouseMove(MouseEventArgs e) 
        { 
            base.OnPreviewMouseMove(e); 
 
            if (this.IsMouseCaptured) 
            { 
                if (isDragging) 
                { 
                    Point currentPosition = e.GetPosition(this); 
 
                    double elementLeft = (currentPosition.X - startPoint.X) + selectedElementOrigins.X; 
                    double elementTop = (currentPosition.Y - startPoint.Y) + selectedElementOrigins.Y; 
 
                    Canvas.SetLeft(selectedElement, elementLeft); 
                    Canvas.SetTop(selectedElement, elementTop); 
                } 
            } 
        } 
    } 
}


Window1.xaml:

Code:
<LabWPFLayout2:DragCanvasControl AllowDrop="True" Name="mainCanvas"  DragEnter="mainCanvas_DragEnter" Drop="mainCanvas_Drop" />



Window1.xaml.cs:

Code:
private void treeConnections_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
        { 
            draggedItem = sender as TreeViewItem; 
            startDragPoint = e.GetPosition(null); 
        } 
 
        private void treeConnections_PreviewMouseMove(object sender, MouseEventArgs e) 
        { 
            if (e.LeftButton == MouseButtonState.Pressed) 
            { 
                Point position = e.GetPosition(null); 
 
                if (Math.Abs(position.X - startDragPoint.X) > SystemParameters.MinimumHorizontalDragDistance || Math.Abs(position.Y - startDragPoint.Y) > SystemParameters.MinimumVerticalDragDistance) 
                { 
                    // User is dragging. Set up the drag-drop behaviour. 
                    DragDrop.DoDragDrop(draggedItem, draggedItem.Header, DragDropEffects.Copy); 
                } 
            } 
        } 
 
        private void mainCanvas_DragEnter(object sender, DragEventArgs e) 
        { 
            if (e.Data.GetDataPresent(DataFormats.Text)) 
            { 
                e.Effects = DragDropEffects.Copy; 
            } 
            else 
            { 
                e.Effects = DragDropEffects.None; 
            } 
        } 
 
        private void mainCanvas_Drop(object sender, DragEventArgs e) 
        { 
            // Create a new label. 
            Label newnewLabel = new Label(); 
            newLabel.Content = e.Data.GetData(DataFormats.Text); 
            newLabel.FontSize = 14; 
 
            // Add label to canvas and position. 
            mainCanvas.Children.Add(newLabel); 
            Canvas.SetLeft(newLabel, e.GetPosition(mainCanvas).X); 
            Canvas.SetTop(newLabel, e.GetPosition(mainCanvas).Y); 
        }

As you can see, the drag and drop starts from the tree view. What I would like is that when the label is created within the canvas, the user can then drag that label around the canvas and place it whereever they like.

If you need more of the Window1 code (I didn't put it here to cut down the size of the post), or more details about what I need help with, let me know.

Dev tools: Windows Vista Business SP1, Visual Studio 2008 Profession SP1, .Net framework 3.5 SP1

Thanks,

Adrian Johnson

Adrian Johnson
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top