wpf - 如何在鼠标位置放大或缩小时正确同步 WPF Scrollviewer 和 Canvas
问题描述
我在 WPF (XAML) 代码中使用以下控件来创建画布:
<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>
本质上,这包括一个画布(比我的屏幕分辨率大)和一个滚动查看器,以确保我可以在整个画布上导航。
现在,如果我按住 CTRL 并使用鼠标滚轮,我想在画布的当前鼠标光标位置放大/缩小。使用与此处列出的方法类似的方法,它可以很好地工作。
我的 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;
}
这很好用,但有一个例外:如果我滚动进/出,滚动查看器的滚动条位置和画布的实际位置不再同步。含义:画布放大或缩小,但滚动查看器不调整其滚动条位置,这最终意味着您无法再正确滚动画布。自然地(因为我使用画布绘制需要大量导航的大型图表),我希望能够不时缩小很多,以便整个画布仅填充滚动视野的一部分观众。附加的屏幕截图显示了我放大了很多的情况以进行澄清。
我尝试了其他几种方法,例如首先将滚动查看器移动到鼠标位置,然后应用“scale(...)”操作(没有“AtPrepend”),但无济于事。直接在滚动查看器上执行缩放操作显然也不起作用。可能,解决方案是微不足道的,但我看不到树木的森林......
任何帮助将不胜感激!
解决方案
感谢 BionicCode 的提示。以下条目回答了我的问题并且完美运行:
推荐阅读
- r - terra extract() 在 R 中给出 NA 值
- scala - org.apache.spark.sql.catalyst.encoders.init 从 Azure 事件中心读取并使用 Protobuf 时出现 NoSuchMethodError
- android - 在活动之间传递多个图像
- angularjs - 如何检查AngularJS中是否不存在对象的属性?
- xpath - 我们如何找到类 ng-binding 的 x-path 表达式?
- python - 我怎么做才能让python找到某个重复的单词,在一个文件中计算它并让它做一些事情?
- python - Python 中的 Value_Counts() 输出是一个系列
- c# - 安装 dotnet 工具包时出错,因为“它与 net50 不兼容”
- python - 如何从用户定义的多行字符串中替换所有出现的单词?
- c++ - 提供基于 Saffir-Simpson 量表的飓风类别的程序