Drag a user control but keep it inside its parent's borders in WPF

I have a user control that I drag inside the grid. The Z-Index is set pretty high so I can keep it above the other kids. Dragging and dropping the control works fine, but if the user wants to move the control outside the grid, it will allow it.

enter image description here How can I make it not leave the borders of the parent Grid control, here is what I have now:

private System.Windows.Point _anchorPoint; private System.Windows.Point _currentPoint; private bool _isInDrag; private void UserControl_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { var element = sender as FrameworkElement; _anchorPoint = e.GetPosition(null); if (element != null) element.CaptureMouse(); _isInDrag = true; e.Handled = true; } private void UserControl_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { if (!_isInDrag) return; var element = sender as FrameworkElement; if (element != null) element.ReleaseMouseCapture(); _isInDrag = false; e.Handled = true; } private void UserControl_MouseMove(object sender, MouseEventArgs e) { if (!_isInDrag) return; _currentPoint = e.GetPosition(null); UIElement container = VisualTreeHelper.GetParent(_parentGrid) as UIElement; System.Windows.Point relativeLocation = _parentGrid.TranslatePoint(new System.Windows.Point(0, 0), container); if (_currentPoint.X > relativeLocation.X) return; if(_currentPoint.Y >= relativeLocation.Y)return; _transform.X += _currentPoint.X - _anchorPoint.X; _transform.Y += (_currentPoint.Y - _anchorPoint.Y); RenderTransform = _transform; _anchorPoint = _currentPoint; } 

"relativeLocation" is always 0x0, so it does not work. Any ideas would be greatly appreciated.

* Note. I know that if I changed my UserControl to Window, it would reduce all the problems that I have. But honestly, it looks great, and I really don't want to clutter up the window. This system opens as a control panel, which consumes the entire user window (opens in a separate window). Therefore, when you open a window here, it does not flow directly.

+5
source share
2 answers

I do not think you need a relative location. However, math can be a little annoying to get it right. Try this approach, it worked well when I tested it:

  private void UserControl_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; if (rightEdge > _parentGrid.Width) delta.X = 0; if (bottomEdge > _parentGrid.Height) delta.Y = 0; //Apply the delta to the user control _transform.X += delta.X; _transform.Y += delta.Y; RenderTransform = _transform; _anchorPoint = _currentPoint; } 
+1
source

This is the beginning:

 Point position = _parentGrid.PointToScreen(new Point(0, 0)); PresentationSource source = PresentationSource.FromVisual(_parentGrid); position = source.CompositionTarget.TransformFromDevice.Transform(position); 

Now you have the screen coordinates of the parent grid. The Transform() call is important because it converts the pixels into device-independent pixel pixels corresponding to the DPI setting of the system.

+1
source

All Articles