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.
-
The control moves although you released the mouse button? Then I'd suggest to log the `MouseDown`, `MouseUp` and `OnDrag`, the latter with the value of `isDragging`, e.g. into a ListView. It would be good to know why `isDragging` doesn't become `false`. – Yogu Dec 21 '11 at 21:01
-
I'm not sure I understand what you're saying Yogu. What do you think the problem could be?> – Dot NET Dec 21 '11 at 21:04
-
possible duplicate of [Unusual dragging issue](http://stackoverflow.com/questions/8579521/unusual-dragging-issue) – Hans Passant Dec 21 '11 at 21:07
-
The problem is that the control moves although the mouse button is no longer pressed, right? Then, `isDragging` must be true; otherwise, it wouldn't move. Therefore, the question is, why `isDragging` is true, although `MusicNote_MouseUp` must have set it to `false` before. To answer that question, we have to find out in which order the methods are called. For example, one reason could be that `MusicNote_MouseUp` doesn't get called. Or that `MusicNote_MouseDown` is called afterwards. To be honest, I really don't know how this could happen. – Yogu Dec 21 '11 at 21:09
-
It's not a duplicate question, read it properly please. It's the same code but a different issue. In the other question, the note wouldn't move at all. Now it moves but jitters. – Dot NET Dec 21 '11 at 21:09
-
@Yogu Thanks very much for your input, however it only moves when the mouse is pressed. The problem is that while it moves, it jitters/vibrates. – Dot NET Dec 21 '11 at 21:10
-
Ok, then I misunderstood *When the dragging is done, ...*. Sorry for that. Wait a moment, I'm writing an answer. – Yogu Dec 21 '11 at 21:15
1 Answers
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
, 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.- Next, add
gridDelta
tothis.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 - sogridDelta
is 30.newTop = this.Top + 30
- Check whether
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.

- 9,165
- 5
- 37
- 58
-
Thank you very much - what you're suggesting goes instead of the 'if statements', or can it be integrated with them? Again many thanks for the help. – Dot NET Dec 21 '11 at 22:03
-
The concept I've presented replaces your `if` statements. You had a `if` statement for every tone; my code handles every possible tone. – Yogu Dec 21 '11 at 22:17