【问题标题】:Track Bar Only fire event on final value not ever time value changesTrack Bar 仅在最终值上触发事件,而不是时间值更改
【发布时间】:2012-03-02 12:05:32
【问题描述】:

我正在开发一个非常基本的 C# Visual Studio 表单应用程序,但是在让轨迹栏按我想要的方式运行时遇到了一些问题,因此希望社区中的某个人可能对此有解决方案。

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

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

【问题讨论】:

  • 请不要在标题前加上“C# Visual Studio 2010”之类的前缀。这就是标签的用途。

标签: c# visual-studio-2010 trackbar


【解决方案1】:

如果用户点击了轨迹栏,只需检查一个变量。如果是,请延迟输出。

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。

【讨论】:

  • 为什么不直接关闭 MouseUp 事件呢?无论如何,这不只会在 MouseUp 上触发吗?
【解决方案2】:

尝试MouseCaptureChanged 事件 - 这是最适合此任务的方法

【讨论】:

    【解决方案3】:

    用户还可以在短时间内多次移动轨迹栏,或者多次单击轨迹以增加拇指而不是拖动拇指。所有这些都是额外的情况,在“拇指移动”结束时注册的值并不是用户真正想要的最终值。

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

    【讨论】:

      【解决方案4】:

      trackbar_valuechanged 事件处理程序试试这个:

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

      【讨论】:

        【解决方案5】:

        我发现一个相当可靠的方法是使用在 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();
            }
        }
        

        【讨论】:

          【解决方案6】:

          我刚才遇到了这个问题,因为我正在实现一个内置的视频播放器,并且希望用户能够更改视频的位置,但我不想通过发送 SetPosition 来重载视频播放 API调用用户在前往其最终目的地的途中经过的每一个滴答声。

          这是我的解决方案:

          首先,方向键是个问题。您可以尽力通过计时器或其他机制来处理箭头键,但我发现它比它值得更痛苦。因此,如@Matthias 所述,将属性 SmallChange 和 LargeChange 设置为 0。

          对于鼠标输入,用户将不得不点击向下,移动它,然后松开,这样处理鼠标按下、鼠标向上和轨迹栏的滚动事件,如下所示:

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

          【讨论】:

            【解决方案7】:

            我遇到了类似的问题,只是使用了范围 TrackBar 控件。同样的想法也适用于此,只是这种情况更容易。

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

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

            【讨论】:

              【解决方案8】:

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

              1. 捕捉 Trackbar-ValueChange-Event
              2. 在 value-change 事件中禁用 valuechange 事件并启用 MouseUp-Event
                  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 移动,则此方法有效。也可以通过键盘移动轨迹栏。然后必须实现进一步的代码来处理这个事件。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2011-09-29
                • 1970-01-01
                • 1970-01-01
                • 2013-08-22
                • 1970-01-01
                • 2021-10-03
                • 1970-01-01
                相关资源
                最近更新 更多