跟踪栏仅在最终值上触发事件而不是时间值更改

我正在研究一个非常基本的C#visual studio表单应用程序,但是我遇到了一些问题,因为我希望它能够让跟踪栏按照我的意愿行事,所以希望社区中的某个人可以为此提供解决方案。

我所拥有的是一个非常基本的应用程序,主要部分是一个值为0到100的轨迹栏。用户设置轨道的值来表示“要执行的工作量”,此时程序可以达到一些设备并告诉他们做“x”工作量(x是轨迹栏的值)。 所以我所做的是使用轨迹栏滚动事件来捕捉轨迹栏值何时发生变化以及处理程序内部调用设备并告诉他们要做多少工作。

我的问题是我的事件处理程序是为轨道栏当前所在的位置和结束位置之间的每个值调用的。 因此,如果它从10滑动到30,我的事件处理程序被调用20次,这意味着我正在接触我的设备并告诉他们运行我甚至不希望它们运行的​​值。 滚动停止发生时,是否只有事件才能检查最终值?

如果用户单击了轨迹栏,只需检查变量即可。 如果是这样,请延迟输出。

bool clicked = false; trackBar1.Scroll += (s, e) => { if (clicked) return; Console.WriteLine(trackBar1.Value); }; trackBar1.MouseDown += (s, e) => { clicked = true; }; trackBar1.MouseUp += (s, e) => { if (!clicked) return; clicked = false; Console.WriteLine(trackBar1.Value); }; 

对于提到的@roken问题,您可以将LargeChangeSmallChange设置为0。

尝试使用MouseCaptureChanged事件 – 这是此任务的最佳选择

用户还可以在短时间内多次移动轨迹条,或者多次单击轨道以增大拇指而不是拖动拇指。 所有这些都是额外的情况,其中在“拇指移动”结束时注册的值实际上不是您的用户期望的最终值。

听起来您需要一个确认更改的按钮,然后捕获轨迹栏的当前值并将其发送到您的设备。

我发现一个相当可靠的方法是使用连接在trackbar.Scroll事件中的计时器:

 private Timer _scrollingTimer = null; private void trackbar_Scroll(object sender, EventArgs e) { if (_scrollingTimer == null) { // Will tick every 500ms (change as required) _scrollingTimer = new Timer() { Enabled = false, Interval = 500, Tag = (sender as TrackBar).Value }; _scrollingTimer.Tick += (s, ea) => { // check to see if the value has changed since we last ticked if (trackBar.Value == (int)_scrollingTimer.Tag) { // scrolling has stopped so we are good to go ahead and do stuff _scrollingTimer.Stop(); // Do Stuff Here . . . _scrollingTimer.Dispose(); _scrollingTimer = null; } else { // record the last value seen _scrollingTimer.Tag = trackBar.Value; } }; _scrollingTimer.Start(); } } 

使用trackbar_valuechanged事件处理程序尝试:

 trackbar_valuechanged(s,e) { if(trackbar.value == 10){ //Do whatever you want } else{ //Do nothing or something else } } 

我刚才有这个问题,因为我正在实现一个内置的video播放器,并希望用户能够改变video的位置,但我不想通过发送每个SetPosition调用来重载video播放API。勾选用户在去往他/她的最终目的地的路上。

这是我的解决方案:

首先,箭头键​​是个问题。 您可以尝试通过计时器或其他机制处理箭头键,但我发现它比它的价值更痛苦。 因此,当@Matthias提到时,将属性SmallChange和LargeChange设置为0。

对于鼠标输入,用户将不得不单击,移动它,然后松开以便处理跟踪栏的MouseDown,MouseUp和Scroll事件,如下所示:

  private bool trackbarMouseDown = false; private bool trackbarScrolling = false; private void trackbarCurrentPosition_Scroll(object sender, EventArgs e) { trackbarScrolling = true; } private void trackbarCurrentPosition_MouseUp(object sender, MouseEventArgs e) { if (trackbarMouseDown == true && trackbarScrolling == true) Playback.SetPosition(trackbarCurrentPosition.Value); trackbarMouseDown = false; trackbarScrolling = false; } private void trackbarCurrentPosition_MouseDown(object sender, MouseEventArgs e) { trackbarMouseDown = true; } 

我有一个类似的问题,只有一个范围的TrackBar控件。 同样的想法也适用于此,只有这种情况更容易。

我在TrackBar上处理MouseUp事件以启动我需要的程序,只有在你松开鼠标按钮之后。 如果您将条拖动到所需位置或只是单击它,则此方法有效。

private void rangeTrackBarControl1_MouseUp(object sender,System.Windows.Forms.MouseEventArgs e){YourProcedureHere(); }