2017-10-09 76 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(); 
      } 
     } 
    } 

所以它幾乎是相同的,但與反被應用到鼠標拖拽......,這就是它!