WPF在放大或缩小时拖动listboxitems
我有一个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。显然,它应该在什么位置和基于缩放级别的位置之间存在某种关系,但我不知道它是什么。
我不知道这里是否有标准的解决方案,但当然我会很感激一些指导。
谢谢。
好吧,良好的互联网礼仪是回复,如果我找到了解决方案(我做了)。
我玩过几个想法...但我似乎没有意识到的主要原因是,对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();
}
}
}
所以它几乎是相同的,但与反被应用到鼠标拖拽......,这就是它!