Question

This may be a very basic question. I have a canvas, which I put different Elements on in runtime (TextBoxes, Shapes, Buttons). Now I want to be able to drag and drop those elements to another location on the same canvas.

Can anyone provide me with some code, how to implement something like onDrag in runtime?

Was it helpful?

Solution

You can use for example the MouseDown, MouseMove and MouseUp events and then the MouseEventArgs's GetPosition(element) that returns you the coordinates relative to element (there are more events that expose this method).

Also, take advantage of the RoutedEvent's OriginalSource to check which element inside the canvas was clicked (in this case it's only the rectangle).

Here's an example:

<Grid>
    <Canvas Name="MyCanvas" PreviewMouseLeftButtonDown="OnMouseDown" MouseMove="OnMouseMove">
        <Rectangle Width="20" Height="20" Canvas.Left="10" Canvas.Top="10" Fill="Blue"/>
        <Rectangle Width="20" Height="20" Canvas.Left="50" Canvas.Top="10" Fill="Red"/>
    </Canvas>
</Grid>

Code-behind:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        AddHandler(Mouse.MouseUpEvent, new MouseButtonEventHandler(OnMouseUp), true);

    }

    private bool _isBeingDragged;

    public void OnMouseDown(object sender, MouseEventArgs args)
    {
        if (!(args.OriginalSource is Canvas))
        {
            _isBeingDragged = true;
        }
    }

    public void OnMouseMove(object sender, MouseEventArgs args)
    {
        if (_isBeingDragged)
        {
            var elementBeingDragged = (FrameworkElement) args.OriginalSource;
            var position = args.GetPosition(MyCanvas);
            Canvas.SetLeft(elementBeingDragged, position.X - elementBeingDragged.ActualWidth / 2);
            Canvas.SetTop(elementBeingDragged, position.Y - elementBeingDragged.ActualHeight / 2);                
        }
    }

    public void OnMouseUp(object sender, MouseEventArgs args)
    {
        _isBeingDragged = false;
    }

}

I had to use the UIElement's AddHandler method to register MouseUp because somehow it has being marked as Handled (the AddHandler method allows you to register an event handler for events that have been handled previously, i.e. e.Handled = true)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top