轨迹栏仅在最终值时触发事件,而不会更改时间值
本文关键字:时间 事件 轨迹 | 更新日期: 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提到的问题,您可以将LargeChange
和SmallChange
设置为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();}
我用两个事件解决了应用程序的问题:
- 捕获Trackbar ValueChange事件
- 在值更改事件中,禁用值更改事件并启用鼠标上移事件
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移动,则此操作有效。也可以通过键盘移动轨迹栏。然后必须实现进一步的代码来处理此事件。