2016-06-30 7 views
5

グリッド内でドラッグしているユーザーコントロールがあります。私が他の子供の上にそれを保つことができるようにZ - インデックスはかなり高く設定されています。コントロールをドラッグすると完全に機能しますが、グリッドの外にコントロールを移動したい場合は、グリッドを許可します。ユーザーコントロールをドラッグしますが、親の境界内にWPFで保持します

enter image description here は私が親グリッドコントロールの境界を残してからそれを維持するにはどうすればよい、ここで私が今持っているものです。

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

に動作していないthatsのように、「relativeLocation」は、常に0x0です。どんなアイデアでも大歓迎です。

*注:UserControlをWindowに変更した場合、私が抱えている問題をすべて緩和できます。しかし、正直言って、それはこのように素晴らしいと私は本当にウィンドウを乱雑にしたくないです。このシステムは、ユーザーの「ウィンドウ全体」(別のウィンドウで開く)を消費するダッシュボードとして開きます。だから、ここで窓を開くと、その窓は右に流れません。

+0

「parentGrid」のコンテナへの相対的な位置を計算しているようです。これはゼロ点を説明するものです。代わりに 'UserControl'をコンテナに入れてください。ref [this post](http://stackoverflow.com/a/1923775)。 – bab7lon

答えて

1

私はあなたが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; 
    } 
1

これがスタートです:

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

は今、あなたは親グリッドの画面座標を持っています。 Transform()への呼び出しは、システムのDPI設定に一致するピクセルをWPFデバイスに依存しないピクセルに変換するので重要です。

関連する問題