轨迹栏仅在最终值时触发事件,而不会更改时间值

本文关键字:时间 事件 轨迹 | 更新日期: 2023-09-27 18:23:53

我正在开发一个非常基本的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_valuechanged事件处理程序:

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

我发现一种相当可靠的方法是使用连接在轨迹栏中的计时器。滚动事件:

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();
    }
}

我刚才在实现内置视频播放器时遇到了这个问题,我希望用户能够更改视频的位置,但我不想让视频回放API过载,因为用户在到达他/她的最终目的地的路上经过的每个节拍都会发送SetPosition调用。

这是我的解决方案:

首先,箭头键是个问题。你可以尽量通过计时器或其他机制来处理箭头键,但我发现这比它值得的更痛苦。因此,如@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(对象发送器,System.Windows.Forms.MouseEventArgs e){YourProcedureHere();}

我用两个事件解决了应用程序的问题:

  1. 捕获Trackbar ValueChange事件
  2. 在值更改事件中,禁用值更改事件并启用鼠标上移事件
    public MainWindow()
        {
            //Event for new Trackbar-Value
            trackbar.ValueChanged += new System.EventHandler(trackbar_ValueChanged);
        }
    
    private void trackbar_ValueChanged(object sender, EventArgs e)
        {
            //enable Trackbar Mouse-ButtonUp-Event
            trackbar.MouseUp += ch1_slider_MouseUp;
            //disable Trackbar-ValueChange-Event
            trackbar.ValueChanged -= ch1_slider_ValueChanged;
        }
        private void trackbar_MouseUp(object sender, EventArgs e)
        {
            //enable Trackbar-ValueChange-Event again
            trackbar.ValueChanged += new System.EventHandler(trackbar_ValueChanged);
            //disable Mouse-ButtonUp-Event
            trackbar.MouseUp -= trackbar_MouseUp;
            //This is the final trackbar-value
            textBox.AppendText(trackbar.Value);
        }

注意:如果轨迹栏被mose移动,则此操作有效。也可以通过键盘移动轨迹栏。然后必须实现进一步的代码来处理此事件。