2016-06-30 13 views
5

Mam kontrolę użytkownika, którą przeciągam do wnętrza siatki. Indeks Z jest ustawiony dość wysoko, więc mogę utrzymać go nad innymi dziećmi. Przeciąganie kontrolki działa doskonale, ale jeśli użytkownik chce przenieść kontrolkę poza siatkę, pozwoli na to.Przeciągnij kontrolkę użytkownika, ale trzymaj ją wewnątrz granic jej rodzica w WPF

enter image description here jaki sposób utrzymać ją przed opuszczeniem granic sterowania sieci macierzystej, tutaj jest to, co mam teraz:

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

W „relativeLocation” jest zawsze 0x0, więc to nie działa. Wszelkie pomysły będą mile widziane.

* Uwaga: Wiem, że jeśli zmienię UserControl na okno, zmniejszyłbym wszystkie problemy, które mam. Ale szczerze mówiąc, wygląda świetnie w ten sposób i naprawdę nie chcę zagracać okna. Ten system otwiera się jako pulpit nawigacyjny, który zużywa całe okno użytkownika (jest otwierane w oddzielnym oknie). Więc kiedy otworzysz tutaj okno, jego przepływ nie jest prawidłowy.

+0

Wygląda na to, że obliczasz względną lokalizację kontenera 'parentGrid' na jego kontener. Co wyjaśniłoby punkt zerowy. Zamiast tego spróbuj użyć 'UserControl' do swojego kontenera, patrz [this post] (http://stackoverflow.com/a/1923775). – bab7lon

Odpowiedz

1

Nie sądzę, że potrzebujesz względnej lokalizacji. Jednak matematyka może być nieco denerwująca, aby uzyskać prawo. Spróbuj tego podejścia, to działa dobrze, gdy testowałem go:

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

To jest początek:

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

Teraz masz współrzędne ekranie siatki macierzystej. Połączenie z Transform() jest ważne, ponieważ spowoduje konwersję pikseli na piksele niezależne od urządzenia WPF, pasujące do ustawienia DPI systemu.