簡體   English   中英

拖動用戶控件,但將其保留在WPF中其父級的邊界內

[英]Drag User Control, but keep it inside the bounds of its parent in WPF

我有一個用戶控件,我在網格內拖動。 Z-Index設置得相當高,以便我可以將它保持在其他孩子之上。 拖動控件可以很好地工作,但如果用戶想要將控件移出網格外,它將允許它。

在此輸入圖像描述 如何防止它離開父Grid控件的邊界,這是我現在擁有的:

   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”始終為0x0,因此不起作用。 任何想法將不勝感激。

*注意:我知道如果我將UserControl更改為Window,它將減輕我遇到的所有問題。 但說實話,這種方式看起來很棒,而且我真的不想讓窗戶混亂。 該系統打開為儀表板,消耗用戶的整個窗口(在單獨的窗口上打開)。 所以當你在這里打開一個窗口時,它不會向右流動。

我認為你不需要relativeLocation。 不過,數學可能有點煩人。 嘗試這種方法,我測試時效果很好:

    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;
    }

這是一個開始:

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

現在您擁有父網格的屏幕坐標。 Transform()的調用很重要,因為它會將像素轉換為與WPF設備無關的像素,與系統DPI設置相匹配。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM