Mouse click near subdivision dash of trackbar

124 Views Asked by At

I am using a C# System.Windows.Forms.TrackBar instance with the following options

  • Minimum = 0
  • Maximum = 10
  • SmallStep = 1
  • LargeChange = 5

And I want to select the nearest subdivision dash of trackbar if a mouse has been clicked on trackbar. A mouse click near the first dash for example should select first dash. A mouse click near the seventh dash should select seventh dash.

In my current configuration I am only able to select the first, fifth and tenth dash with a mouse click.

So I changed LargeChange to 1. This only works for me if I am clicking sequential. If I click near the first, second, third dash one after the other, the first, second, and third dash is selected accordingly. But if I click near the seventh dash, the fourth dash is selected.

Therefore I used TrackBar.MouseDown event and the following code to set the desired dash:

private void CameraFocusTrackBar_OnMouseDown(object sender, MouseEventArgs e)
{
  double Step = ((double)e.X / (double)mCameraFocusTrackBar.Width) * (mCameraFocusTrackBar.Maximum - mCameraFocusTrackBar.Minimum) + mCameraFocusTrackBar.Minimum;

  Console.WriteLine("OnMouseDown Step: " + Convert.ToInt32(Step));
  mCameraFocusTrackBar.Value = Convert.ToInt32(Step);
}

This works as expected. However I did not receive any TrackBar.MouseDown events if I click on trackbar slider, did not release left mouse button and move trackbar slider.

So I thought I have to use TrackBar.Scroll event.

private void CameraFocusTrackBar_OnScroll(object sender, EventArgs e)
{
  int Step = mFocusTrackBar.Value;

  Console.WriteLine("Scroll Step: " + Step);
}

And this function shows the same beaviour as above. It only works for me if I am clicking sequential. If for example I click near the second dash and then near the tenth dash, I see the following steps:

Scroll Step: 2
OnMouseDown Step: 2

Scroll Step: 3
OnMouseDown Step: 10

In this situation I should use OnMouseDown Step.

And if I click and move trackbar slider, I see the following steps:

OnMouseDown Step: 6
Scroll Step: 7
Scroll Step: 8
Scroll Step: 9
Scroll Step: 10
Scroll Step: 11

In this situation I should use Scroll Step.

Does anybody know a solution?

2

There are 2 best solutions below

0
QuicheLorraine On BEST ANSWER

I found a solution based on on the idea of @Idle_Mind.

1.) I put the code of Idle_Mind in a new ExtTrackBar class.

2.) I added a mLastValue member, storing last value of trackbar. Furthermore I use this member to filter events so no double events with the same value occur.

3.) I added event function for MouseWheel event. Based on MouseEventArgs.Delta I increment oder decrement mLastValue and set trackbar value.

3.) I added event function for Scroll event. There I set trackbar value to mLastValue to overwrite behaviour in case of mouse wheel.

4.) I implemented a own event to inform user about a new set value.

1
Idle_Mind On

Handle both the MouseDown and the MouseMove events like this:

private void mCameraFocusTrackBar_MouseDown(object sender, MouseEventArgs e)
{
    SetTrackBar((double)e.X / mCameraFocusTrackBar.Width);
}

private void mCameraFocusTrackBar_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button == MouseButtons.Left)
    {
        SetTrackBar((double)e.X / mCameraFocusTrackBar.Width);
    }
}

private void SetTrackBar(double p)
{
    int newValue = mCameraFocusTrackBar.Minimum + (int)(p * (mCameraFocusTrackBar.Maximum - mCameraFocusTrackBar.Minimum + 1));
    mCameraFocusTrackBar.Value = Math.Min(mCameraFocusTrackBar.Maximum, Math.Max(mCameraFocusTrackBar.Minimum, newValue));
}

Here's an example of it in action:

enter image description here