我想做什么:我目前正在WPF应用程序中托管OpenTK glControl(通过WindowsFormsHost
)。该应用程序有许多按钮,但我们将专注于暂停和播放按钮。我使用VBO,这就是我为GL.DrawArrays(PrimitiveType.LineStrip, 0, frameCount );
制作动画的方式。它绘制了从0到framecount
的顶点范围,所以当我点击播放时,它只是开始递增framecount
,它开始动画。只使用鼠标,一切都很完美。
问题:我的应用程序也需要使用触摸屏(FWIW,当我说触摸时,WPF将其视为手写笔,而不是触摸)。当应用程序没有动画时,触摸会像它应该的那样工作,我不会处理触摸事件,因此触摸按钮只会引发Click
事件。如果我们没有动画,我就不会有任何问题。因此,当我使用我的鼠标Click
播放按钮时,UI仍然响应我的鼠标(点击工作,徘徊改变颜色,等等),但接触似乎在一段时间内被忽略。我必须触摸一个按钮3到5次才能完成它应该做的事情(比如暂停)。让我们回过头来,现在我们还没有动画,这次,如果我触摸播放按钮来举起Click
事件,它将开始制作动画,但我的触摸现在有同样的问题,必须触摸多个提升Click
事件的时间,最重要的是,UI现在不响应鼠标(WindowsFormsHost仍然正确地响应鼠标事件)。单击按钮或将鼠标悬停在按钮上并没有做任何事情。直到我再次暂停动画,UI才开始再次响应鼠标。
我尝试了什么(我认为)我知道:当UI停止响应鼠标输入并且触摸输入被弄乱时,如果我使用MOUSE或TOUCH点击我的任何地方应用程序,它按预期工作。这让我相信它不是触摸屏驱动程序问题或任何东西。我还使用Snoop来查看正在引发(或不发生)的事件,以便看到手写笔和鼠标被捕获和释放以及焦点是什么。我找不到一个没有发布的实例。如果有人愿意,我可以发布Snoop结果,显示鼠标和触摸点击之间的差异。我尝试将预览鼠标放在MainWindow上,但在TOUCHING播放后,没有鼠标点击引发此事件,触摸播放按钮后第一次触摸会触发此事件。我也尝试隐藏WindowsFormsHost,鼠标和触摸点击所有工作就像他们应该减去glControl。因为我隐藏了WindowsFormsHost,所以paint事件永远不会被触发,这让我相信paint函数可能存在问题。我知道这个错误WPF Touch Bug,但我并不认为这是我的问题。有些东西告诉我互操作是给我带来问题的,但我不确定。
我的代码:
private void playFwdFunc()
{
//disable undrawing and enable drawing
undraw = false;
draw = true;
//unpause animation
paused = false;
//enable/disable appropriate buttons
pauseBtn.IsEnabled = true;
stepBackBtn.IsEnabled = false;
stepFwdBtn.IsEnabled = false;
clearStart.IsEnabled = true;
clearCurrent.IsEnabled = true;
//refresh control
glControl1.Invalidate();
}
private void playFwdClick(object sender, RoutedEventArgs e)
{
playFwdFunc();
}
在我的glPaint活动中:
if (frameCount < vertices.Length && !paused)
{
//draw more vertices
if (draw)
{
if (0 < (int)(vertices.Length / (25000 / speedTrack.Value)))
frameCount += (int)(vertices.Length / (25000 / speedTrack.Value));
else
frameCount++;
}
//draw less vertices
else if (undraw)
{
if (0 < (int)(vertices.Length / (25000 / speedTrack.Value)))
frameCount -= (int)(vertices.Length / (25000 / speedTrack.Value));
else
frameCount--;
}
//make sure we dont have a negative framecount (null pointer)
if (frameCount < 0)
{
paused = true;
frameCount = 0;
// manageCodeBox();
}
//make sure we dont exceed # of vertices (null pointer)
else if (frameCount > vertices.Length)
{
frameCount = vertices.Length;
paused = true;
// manageCodeBox();
}
}
我的问题:为什么点击鼠标按钮会让UI做出与触摸按钮不同的反应,即使他们举起同样的事件?任何意见都表示赞赏。
答案 0 :(得分:0)
所以我找到了造成这种行为的原因,在我的绘画功能中,我不断提出一个有glControl1.Invalidate()
的事件。
我最好的猜测:我唯一真正的猜测是,某些事件,如触控线程上发生的触摸,在调用glControl1.Invalidate()
时如何进入与UI线程的实时锁定。我认为这就是为什么一些接触被接受,但UI线程永远不会到达鼠标事件监听器。正如我所说:最好的猜测。
我的解决方法:我最初拨打DispatcherTimer
来致电glControl1.Invalidate()
。鼠标事件运行正常,但由于触摸被提升为鼠标点击,除非我处理触摸事件(我不想对我的UI上的每个按钮执行),否则会有延迟。到目前为止,我的下一个解决方案似乎正在发挥作用。
在我的windows构造函数中:CompositionTarget.Rendering += invalidateProcessor;
。
功能:
private void invalidateProcessor(object sender, EventArgs e)
{
Dispatcher.BeginInvoke(new Action(() => { if (!paused) glControl1.Invalidate(); }), DispatcherPriority.Background);
}
我选择了DispatcherPriority.Background
,因为较高优先级会再次导致触摸延迟。