C# WinForm 中异常拖动问题
我有一个可以由用户拖动的 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你的代码不太符合逻辑。它表示:如果用户将注释向下拖动一个像素,则注释将向下一级设置。如果鼠标向一侧移动,则鼠标每移动一个像素,注释就会向下移动一步。
我建议回到概念。
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.
delta = e.Y - currentY
.Then, snap it into the grid:
gridDelta = delta / step * step
, wherestep
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.gridDelta
tothis.Top
and check if the result is within the range.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 - sogridDelta
is 30.newTop = this.Top + 30
newTop
is within the range, and then assign it tothis.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.