所以这是我的问题,我希望我能够以适当的方式提出这个问题。
简而言之:如何在WPF中顺利缩放?
详细信息:我正在WPF中编写一个CAD应用程序,当MouseWheel
事件被触发时,我正在重绘部分屏幕。
private void ModelWindowBorder_MouseWheel(object sender, MouseWheelEventArgs e)
{
var zoom = e.Delta > 0 ? 0.2 : -0.2;
// increase or decrease the scale by *zoom*
// Redraw Screen
// Apply TransformScale and etc.
}
实际上上面的代码是有效的,但我不满足于它有两个原因:
当我不得不重新绘制屏幕上的大量视觉效果时,它会错过被触发的多个MouseWheel
事件。因此,如果要在一个大滚动中触发8个MouseWheel事件,则只会触发4-5个事件。这使缩放有点慢。
第二个原因可能与WPF无关。 var zoom = e.Delta > 0 ? 0.2 : -0.2;
是否应该增加/减少比例?对我来说似乎不合适。因为当我们缩小时,当我们放大一步时差异似乎相当大,但是一旦我们接近绘图,将缩放增加一步似乎并不多。
我想知道你对这两个问题的答案和评论。
答案 0 :(得分:3)
您应该考虑e.Delta
的值。
不
var zoom = e.Delta > 0 ? 0.2 : -0.2;
但
var zoom = e.Delta * k;
k
是double
因素,它是设备 specific
此值的有效上限和下限可能来自设备实现或引发事件的其他调用者,因此未定义
但正如你所说一个大卷轴,它的价值更高。
查找k
的一种可能解决方案是获取第一个MouseWheel
事件并使用已接收的值作为起点。如果您收到该值的两倍,则将两个或多个鼠标滚轮组合成单个事件。或者一直进行校准,记住最小值和更改因子。由你决定。
使用乘法而不是添加平坦值。
组合解决方案将如下所示
st.ScaleX *= e.Delta * k;
答案 1 :(得分:1)
一个简单的尝试和coelesce MouseWheel事件是使用Rx。您可以使用.FromEventPattern()方法来使用Wheel事件,只关心那些满足delta容差的事件。 Rx有点棘手,但可以帮助您获得更简单的代码路径。
请参阅此回答 - Detect scroll is completed with PointerWheelChanged