C# WinForm 中异常拖动问题

发布于 2024-12-22 17:56:36 字数 63 浏览 2 评论 0原文

我有一个可以由用户拖动的 PictureBox。拖动完成后,组件看起来会不断地从一侧移动到另一侧,就像振动一样。

I've got a PictureBox which can be dragged by the user. When the dragging is done, the component appears to move continuously from side to side, like vibrating.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

总攻大人 2024-12-29 17:56:36

你的代码不太符合逻辑。它表示:如果用户将注释向下拖动一个像素,则注释将向下一级设置。如果鼠标向一侧移动,则鼠标每移动一个像素,注释就会向下移动一步。

我建议回到概念。

  • 首先,必须确定鼠标距离:delta = eY - currentY
  • 然后,将其插入网格:gridDelta = delta / step * step,其中 step 在您的情况下为 10。

    delta / step 表示音符移动的音调数。因为我们使用的是整数,所以这个值是四舍五入的,我们只有整个音调。如果鼠标向上移动 10(= 步长)像素,则选择下一个更高的音调。

    delta / step * step 是必需的,因为一个音调到另一个音调的距离为 10,即如果音符移动了一个音调,则音符应出现在其原始位置上方 10 个像素处。

  • 接下来,将 gridDelta 添加到 this.Top 并检查结果是否在范围内。
  • 最后,将值保存到 this.Top 中。

也许数字更清楚:如果用户在位置 Y=14 处按下鼠标按钮,然后将其拖动到 48,然后释放,则在最后一次调用 OnDrag 时会发生以下情况:

  • delta = 48 - 14 - delta 为 34。
  • gridDelta = 34 / 10 * 10 - 34/10 = 3; 3 * 10 * 30 - 所以gridDelta是30。
  • newTop = this.Top + 30
  • 检查newTop是否在范围内,然后赋值它到 this.Top

您会看到,尽管用户将注释拖动了 34 像素,但注释仍然比其原始位置高出 30 像素。

像代码中那样的重复通常会导致错误,并且很难调整它们,因此总是寻找更好的算法。

Your code is not very logical. It says: If the user drags the note one pixel downwards, the note is set one step down. If the mouse then is moved sidewards, the note moves down a step for every pixel the mouse is moved.

I'd suggest to go back to concept.

  • At first, the mouse distance has to be determined: delta = e.Y - currentY.
  • Then, snap it into the grid: gridDelta = delta / step * step, where step is 10 in your case.

    delta / step represents the number of tones the note is moved. Because we're using Integers, this value is rounded and we only have whole tones. If the mouse is moved 10 (= step) pixels upward, the the next higher tone is chosen.

    delta / step * step is needed because the distance from one tone to the other is 10, i.e. the note should appear 10 pixels above its original position if it's moved one tone higher.

  • Next, add gridDelta to this.Top and check if the result is within the range.
  • Finally, save the value into this.Top.

Maybe numbers make it clearer: If the user presses the mouse button at position Y=14, then drags it up to 48, and then releases, the following happens in the last call of OnDrag:

  • delta = 48 - 14 - delta is 34.
  • gridDelta = 34 / 10 * 10 - 34/10 = 3; 3 * 10 * 30 - so gridDelta is 30.
  • newTop = this.Top + 30
  • Check whether newTop is within the range, and then assign it to this.Top.

You see, the note then is exactly 30 pixels above its original position, although the user dragged it for 34 pixels.

Repetitions like the ones in your code often lead to errors and it's hard to adjust them, so always look for a better algorithm.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文