0

I am trying to make a UserControl draggable and I'm stuck and I have no idea why.

Basing myself on the answer here: How to drag a UserControl inside a Canvas

This portion of code is where I'm stuck:

private void Control_MouseMove(object sender, MouseEventArgs e)
{
    var userControl= sender as UserControl;

    Point currentPosition = e.GetPosition(userControl);

    var transform = userControl.RenderTransform as TranslateTransform;
    if (transform == null)
    {
        transform = new TranslateTransform();
        userControl.RenderTransform = transform;
    }

    transform.X = currentPosition.X - clickPosition.X;
    transform.Y = currentPosition.Y - clickPosition.Y;
}
}

What happens is that while dragging, the control jumps back and forth from its new position to it's old position.

When I change the above code to:

Point currentPosition = e.GetPosition(null);

The dragging works without the jumping back to the original position, but it is obviously offset. The UserControl in question does not have a parent control (in the sense that this.Parent is null).

The solution might be obvious but I'm just not seeing it. Any ideas?

Community
  • 1
  • 1
mo alaz
  • 4,529
  • 8
  • 30
  • 36

2 Answers2

3

Use LayoutTransform. RenderTransform only makes the UIElement "looks like" it is at the new position. This means that the first time the event triggers (first move), it is working as intended, but thereafter, the position is still at the original position, but it's being render-transformed to look like it has moved - this makes your move event go crazy.

It's still better to wrap your control in a Canvas, in my opinion. Using LayoutTransform is usually not recommended.

Jai
  • 8,165
  • 2
  • 21
  • 52
0

Step1: Add the Properties in UserControl

  Point _anchorPoint;
    Point _currentPoint;
    bool _isInDrag;
    private readonly TranslateTransform _transform = new TranslateTransform();

Step 2: Initialize your Constructor with following EventHandlers

  this.MouseLeftButtonDown += new MouseButtonEventHandler(Control_MouseLeftButtonDown);
        this.MouseLeftButtonUp += new MouseButtonEventHandler(Control_MouseLeftButtonUp);
        this.MouseMove += new MouseEventHandler(Control_MouseMove);

3.Implement the Event Methods

 private void Control_MouseMove(object sender, MouseEventArgs e)
    {
        if (!_isInDrag) return;
        _currentPoint = e.GetPosition(null);

        //This is the change to the position that we want to apply
        Point delta = new Point();
        delta.X = _currentPoint.X - _anchorPoint.X;
        delta.Y = _currentPoint.Y - _anchorPoint.Y;

        //Calculate user control edges
        var leftEdge = Margin.Left + _transform.X + delta.X;
        var topEdge = Margin.Top + _transform.Y + delta.Y;
        var rightEdge = Width + Margin.Left + _transform.X + delta.X;
        var bottomEdge = Height + Margin.Top + _transform.Y + delta.Y;

        //Set the delta to 0 if it goes over _parentGrid edges
        if (leftEdge < 0) delta.X = 0;
        if (topEdge < 0) delta.Y = 0;
        //_ParentGridName is called from MDIParent.GridName
        if (rightEdge > _ParentGridName.Width) delta.X = 0;
        if (bottomEdge > _ParentGridName.Height) delta.Y = 0;

        //Apply the delta to the user control
        _transform.X += delta.X;
        _transform.Y += delta.Y;
        RenderTransform = _transform;
        _anchorPoint = _currentPoint;
    }


private void Control_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        if (_isInDrag)
        {
            var element = sender as FrameworkElement;
            element.ReleaseMouseCapture();
            _isInDrag = false;
            e.Handled = true;
        }
    }


 private void Control_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        var element = sender as FrameworkElement;
        _anchorPoint = e.GetPosition(null);
        if (element != null) element.CaptureMouse();
        _isInDrag = true;
        e.Handled = true;
    }