如何在放大或缩小鼠标位置时正确同步 WPF Scrollviewer 和 Canvas
How to correctly synchronize WPF Scrollviewer and Canvas on Zooming in or out on Mouse Position
我在 WPF (XAML) 代码中使用以下控件来创建 canvas:
<ScrollViewer x:Name="CanvasScrollViewer" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible" Background="Beige" >
<Canvas x:Name="canvas" Height="10000" Width="10000" MouseWheel="CanvasMouseWheel" >
<Canvas.RenderTransform>
<MatrixTransform/>
</Canvas.RenderTransform>
</Canvas>
本质上,这包括一个 canvas(大于我的屏幕分辨率)和一个滚动查看器,以确保我可以在整个 canvas.
中导航
现在,如果我按住 CTRL 并使用鼠标滚轮,我想在 canvas 的当前鼠标光标位置 放大/缩小 。使用类似于 here.
所列方法的方法效果很好
我的 C# 代码如下所示:
private void CanvasMouseWheel(object sender, MouseWheelEventArgs e)
{
if (Keyboard.Modifiers != ModifierKeys.Control)
return;
var sentCanvas = sender as UIElement;
var position = e.GetPosition(sentCanvas);
var transform = canvas.RenderTransform as MatrixTransform;
var matrix = transform.Matrix;
var scale = e.Delta >= 0 ? 1.2 : (1.0 / 1.2);
matrix.ScaleAtPrepend(scale, scale, position.X, position.Y);
transform.Matrix = matrix;
e.handled = true;
}
除了一个例外,这工作得很好:如果我滚动进/出,滚动查看器滚动条的位置和 canvas 的实际位置不再同步。含义:canvas 放大或缩小,但滚动查看器不会调整其滚动条位置,这最终意味着您无法再正确滚动 canvas。
自然地(因为我使用 canvas 绘制需要大量导航的大图),我希望能够不时缩小很多,以便整个 canvas 只填充一部分滚动查看器的视野。随附的屏幕截图显示了我缩小了很多的情况。
我尝试了其他几种方法,例如首先将滚动查看器移动到鼠标位置,然后应用“scale(...)”操作(没有“AtPrepend”),但无济于事。直接在scrollviewer上进行缩放操作显然也是不行的。可能,解决方案是微不足道的,但我只见树木不见森林...
如有任何帮助,我们将不胜感激!
感谢 BionicCode 的提示。以下条目回答了我的问题并完美运行:
我在 WPF (XAML) 代码中使用以下控件来创建 canvas:
<ScrollViewer x:Name="CanvasScrollViewer" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible" Background="Beige" >
<Canvas x:Name="canvas" Height="10000" Width="10000" MouseWheel="CanvasMouseWheel" >
<Canvas.RenderTransform>
<MatrixTransform/>
</Canvas.RenderTransform>
</Canvas>
本质上,这包括一个 canvas(大于我的屏幕分辨率)和一个滚动查看器,以确保我可以在整个 canvas.
中导航现在,如果我按住 CTRL 并使用鼠标滚轮,我想在 canvas 的当前鼠标光标位置 放大/缩小 。使用类似于 here.
所列方法的方法效果很好我的 C# 代码如下所示:
private void CanvasMouseWheel(object sender, MouseWheelEventArgs e)
{
if (Keyboard.Modifiers != ModifierKeys.Control)
return;
var sentCanvas = sender as UIElement;
var position = e.GetPosition(sentCanvas);
var transform = canvas.RenderTransform as MatrixTransform;
var matrix = transform.Matrix;
var scale = e.Delta >= 0 ? 1.2 : (1.0 / 1.2);
matrix.ScaleAtPrepend(scale, scale, position.X, position.Y);
transform.Matrix = matrix;
e.handled = true;
}
除了一个例外,这工作得很好:如果我滚动进/出,滚动查看器滚动条的位置和 canvas 的实际位置不再同步。含义:canvas 放大或缩小,但滚动查看器不会调整其滚动条位置,这最终意味着您无法再正确滚动 canvas。 自然地(因为我使用 canvas 绘制需要大量导航的大图),我希望能够不时缩小很多,以便整个 canvas 只填充一部分滚动查看器的视野。随附的屏幕截图显示了我缩小了很多的情况。
我尝试了其他几种方法,例如首先将滚动查看器移动到鼠标位置,然后应用“scale(...)”操作(没有“AtPrepend”),但无济于事。直接在scrollviewer上进行缩放操作显然也是不行的。可能,解决方案是微不足道的,但我只见树木不见森林...
如有任何帮助,我们将不胜感激!
感谢 BionicCode 的提示。以下条目回答了我的问题并完美运行: