2017-10-09 31 views
0

我有一个WPF项目(C#,MVVM,Visual Studio 2010)。WPF在放大或缩小时拖动listboxitems

有一个列表框,其中有项目。如果玩家使用点击和拖动来重新定位它们(​​ItemsPanelTemplate是一个Canvas控件),项目可以自由移动。

它工作正常,但我也有使用鼠标滚轮的放大和缩小方法。

问题是,在放大或缩小状态下,如果拖动ListBoxItem,它不会正常工作。不知怎的,坐标似乎有点偏离。

下面是鼠标滚轮方法:

void OnPreviewMouseWheel(object sender, MouseWheelEventArgs e) 
    { 
     lastMousePositionOnTarget = Mouse.GetPosition(NodeDragCanvas); 

     if (e.Delta > 0) 
     { 
      if (dScaleValue < dZoomMax) 
       dScaleValue += dZoomIncrementValue; 
     } 
     if (e.Delta < 0) 
     { 
      if(dScaleValue > dZoomMin) 
       dScaleValue -= dZoomIncrementValue; 
     } 

     e.Handled = true; 

     scaleTransform.ScaleX = dScaleValue; 
     scaleTransform.ScaleY = dScaleValue; 

     var centerOfViewport = new Point(NodeDragScrollViewer.ViewportWidth/2, NodeDragScrollViewer.ViewportHeight/2); 
     lastCenterPositionOnTarget = NodeDragScrollViewer.TranslatePoint(centerOfViewport, NodeDragCanvas); 
    } 

当然还需要鼠标移动方法:

void OnMouseMove(object sender, MouseEventArgs e) 
    { 
     if (lastDragPoint.HasValue) 
     { 
      Point posNow = e.GetPosition(NodeDragScrollViewer); 

      double dX = (posNow.X - lastDragPoint.Value.X);// *this.dScaleValue; 
      double dY = (posNow.Y - lastDragPoint.Value.Y);// *this.dScaleValue; 

      lastDragPoint = posNow; 

      // This situation is a drag. 
      if (LbNodes.SelectedItems.Count == 0) 
      { 
       NodeDragScrollViewer.ScrollToHorizontalOffset(NodeDragScrollViewer.HorizontalOffset - dX); 
       NodeDragScrollViewer.ScrollToVerticalOffset(NodeDragScrollViewer.VerticalOffset - dY); 
      } 
      else 
      { 
       // This situation is mouse drag of items 
       foreach (ChatNodeViewModel cv in LbNodes.SelectedItems) 
       { 
        cv.XCoord += dX; 
        cv.YCoord += dY; 
       } 

       // This bit just causes the lines between the nodes to update. 
       Mediator.EventMediator.Instance.RefreshAllNodesDraggable(); 
      } 
     } 
    } 

正如你或许可以看到,我试着摸索了一点上面通过将dX和dY乘以比例值。它似乎没有工作。

解释也许更多一点。好吧,假设我们有一个ListBoxItem,它只是一个图像。在正常(默认)缩放级别中,您可以单击该项目并移动它。在移动它时,鼠标光标与ListBoxItem保持相同的位置。在缩放状态下,它会漂移,甚至可能离开ListBoxItem。显然,它应该在什么位置和基于缩放级别的位置之间存在某种关系,但我不知道它是什么。

我不知道这里是否有标准的解决方案,但当然我会很感激一些指导。

谢谢。

回答

0

好吧,良好的互联网礼仪是回复,如果我找到了解决方案(我做了)。

我玩过几个想法...但我似乎没有意识到的主要原因是,对dX和dY应用任何更改也适用于缩放(因为它用于这两个和鼠标拖动) 。

所以我创建了两个单独的变量(dMouseDragX和dMouseDragY)进行实验。我尝试过的第一件事是,因为我意识到如果我放大,漂移会更大,而如果我缩小则漂移会更大,这是为dScaleValue变量创建一个替代方法,当dScale值减少时增加,当dScaleValue减小时增加。这让我更接近了,但还不足以称得上成功。尽管如此,我还是走在了正确的轨道上 - 这是我需要的dScaleValue的逆转。然后......好吧......我用了逆。它的工作。

所以鼠标移动,现在看起来是这样的:

void OnMouseMove(object sender, MouseEventArgs e) 
    { 
     if (lastDragPoint.HasValue) 
     { 
      Point posNow = e.GetPosition(NodeDragScrollViewer); 

      double dX = (posNow.X - lastDragPoint.Value.X); 
      double dY = (posNow.Y - lastDragPoint.Value.Y); 

      // This was a bit of a guess, but it seems to work like a charm. 
      double dMouseDragX = (posNow.X - lastDragPoint.Value.X) * (1/dScaleValue); 
      double dMouseDragY = (posNow.Y - lastDragPoint.Value.Y) * (1/dScaleValue); 


      lastDragPoint = posNow; 

      // This situation is a drag. 
      if (LbNodes.SelectedItems.Count == 0) 
      { 
       NodeDragScrollViewer.ScrollToHorizontalOffset(NodeDragScrollViewer.HorizontalOffset - dX); 
       NodeDragScrollViewer.ScrollToVerticalOffset(NodeDragScrollViewer.VerticalOffset - dY); 
      } 
      else 
      { 
       // This situation is mouse drag of items 
       foreach (ChatNodeViewModel cv in LbNodes.SelectedItems) 
       { 
        cv.XCoord += dMouseDragX; 
        cv.YCoord += dMouseDragY; 
       } 

       // This bit just causes the lines between the nodes to update. 
       Mediator.EventMediator.Instance.RefreshAllNodesDraggable(); 
      } 
     } 
    } 

所以它几乎是相同的,但与反被应用到鼠标拖拽......,这就是它!