【问题标题】:Smooth zoom in WPFWPF 中的平滑缩放
【发布时间】:2014-04-09 15:32:37
【问题描述】:

所以这是我的问题,我希望我能够以适当的方式提出。

简而言之:如何在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.
}

实际上上面的代码可以工作,但我不满意有两个原因:

  1. 当我必须在屏幕上重绘大量视觉效果时,它会错过多个触发的 MouseWheel 事件。因此,如果要在 一个大滚动 中触发 8 个 MouseWheel 事件,则只会触发其中的 4-5 个。这使得缩放有点慢。

  2. 第二个原因可能根本与 WPF 无关。 var zoom = e.Delta > 0 ? 0.2 : -0.2; 是我们应该增加/减少比例的正确方法吗?对我来说这似乎不合适。因为当我们缩小时,当我们放大一级时差异似乎很大,但是一旦我们靠近绘图,放大一级似乎并不多。

我想知道您对这两个问题的回答和意见。

【问题讨论】:

  • 除非您向我们展示您对zoom 变量的实际操作,否则很难回答第二个问题。
  • @Clemens 我实际上将它添加到 ScaleTransform 的 ScaleX/ScaleY 属性中,就像这样 st.ScaleX += zoom;
  • 您可以改为乘以或除以 1.2 等因子。
  • 是的,我想我应该继续努力,但它在第一次尝试时给了我意想不到的结果。
  • 我在一定程度上得到了这个工作。 @Clemens 你对第一个问题有什么建议吗?

标签: c# wpf zooming mousewheel


【解决方案1】:

问题 1。

您应该考虑e.Delta

没有

var zoom = e.Delta > 0 ? 0.2 : -0.2;

但是

var zoom = e.Delta * k;

kdouble 因素,它是设备 specific

此值的有效上限和下限可能来自引发事件的设备实现或其他调用者,因此未定义

但正如你所说的一个大卷轴,它的价值会更高

找到k 的一个可能解决方案是获取第一个MouseWheel 事件并使用收到的值作为起点。如果您收到该值的两倍,则将两个或多个鼠标滚轮滚动组合成单个事件。或者一直进行校准,记住最小值并为其更改因子。由你决定。

问题 2。

使用乘法而不是添加平面值。

组合解决方案将如下所示

st.ScaleX *= e.Delta * k;

【讨论】:

  • 谢谢 Sinatr,我想我看到了希望。你的意思是第一个问题我应该等待滚动完成然后根据收到的输入我应该重绘和缩放屏幕?我有点迷路了。
  • 我只需要实现一种方式,使每个大滚动中的MouseWheel 事件的数量不受重绘过程的影响。我只是不知道该怎么做。
  • 哇 Sinatr,这真是天才,现在我明白你的意思了!这真太了不起了。我希望我能给你我所有的分数!谢谢。
【解决方案2】:

尝试合并 MouseWheel 事件的一个简单方法是使用 Rx。您可以使用 .FromEventPattern() 方法来使用 Wheel 事件,并且只关心那些满足您的 delta 容差的事件。 Rx 有点棘手,但可以帮助您获得更简单的代码路径。

看到这个答案 - Detect scroll is completed with PointerWheelChanged

【讨论】:

  • 谢谢亚当希尔,我现在就去研究一下。
猜你喜欢
  • 1970-01-01
  • 2016-09-11
  • 1970-01-01
  • 2021-10-09
  • 1970-01-01
  • 2010-11-25
  • 2017-01-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多