WPF放大或缩小时拖动列表框项目



我有一个WPF项目(C#、MVVM、Visual Studio 2010)。

有一个ListBox,其中包含项目。如果玩家使用点击和拖动来重新定位项目,则项目可以自由移动(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。显然,根据缩放级别,它应该在哪里和在哪里之间存在一些关系,但我不知道它是什么

我不知道这里是否有标准的解决方案,但我当然希望得到一些指导。

谢谢。

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

我玩了几个主意。。。但我似乎没有意识到的主要一点是,对dX和dY进行任何更改也会应用于缩放(因为它既用于拖动也用于拖动鼠标)。

因此,我创建了两个单独的变量(dMouseDragX和dMouseDragY)进行实验。我尝试的第一件事是创建dScaleValue变量的替代方案,当dScaleValue降低时,漂移会增加,当dSaleValue降低时会增加。这让我更接近了,但还不足以称之为成功。尽管如此,我还是走在了正确的轨道上——这是我需要的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();
}
}
}

所以它几乎是一样的,但相反的是应用于鼠标拖动。。。就这样!

最新更新