C# 在GTK中处理双击

C# 在GTK中处理双击,c#,winforms,user-interface,gtk,gtk#,C#,Winforms,User Interface,Gtk,Gtk#,我正在将WinForms应用程序转换为GTK,我想在GTK DrawingArea小部件上模拟OnMouseDoubleClick方法 在WinForms中,有两种方法可以重写,一种用于单击,另一种用于双击。如果WinForms只检测到一次单击,则它只调用OnMouseSingleClick方法,如果它检测到双击,则它只调用OnMouseSingleClick方法 现在在GTK中,只有一个方法可以覆盖单击,即On Button PressEvent。如果您单击一次,OnButtonPressEv

我正在将WinForms应用程序转换为GTK,我想在GTK DrawingArea小部件上模拟OnMouseDoubleClick方法

在WinForms中,有两种方法可以重写,一种用于单击,另一种用于双击。如果WinForms只检测到一次单击,则它只调用OnMouseSingleClick方法,如果它检测到双击,则它只调用OnMouseSingleClick方法

现在在GTK中,只有一个方法可以覆盖单击,即On Button PressEvent。如果您单击一次,OnButtonPressEvent只会被调用一次,但是如果您双击,它会被调用三次!这是因为GTK为每次单击发送一个信号,再加上双击发送一个信号


这个网站上也有类似的问题,但没有一个答案是关于我正在使用的小部件的,或者答案不令人满意。所以我的问题是,如何用GTK模拟WinForms OnMouseDoubleClick方法?

GTK不提供WinForms实现的行为,可能是因为它需要在真正的单次单击生效之前进行延迟。如果没有延迟,WinForms将在OnMouseDoubleClick之前发出至少一次虚假的OnMouseSingleClick。在同样使用双击打开文件的文件管理器中,使用单击重命名文件时,此延迟非常明显

要自己实现它,您需要在伪代码中执行以下操作:

将布尔等待和未签名的handlerId成员添加到类中。将wait设置为false

当OnButtonPress接收到一次单击且wait为false时:将wait设置为true,并使用GLib.Timeout.Add计划OnWaitForDoubleClickTimeout方法在等于GTK双击间隔的延迟后运行。您可以从中获取作为gtk双击时间属性的双击间隔。存储GLib.Timeout.Add-in handlerId的返回值

当OnButtonPress收到一次单击并等待为true时:通过调用GLib.Source.RemovehandlerId取消超时,将等待重置为false,否则忽略事件

当OnButtonPress接收到双击时:调用OnMouseDoubleClick。此时,由于3,wait应该为false

在OnWaitForDoubleClickTimeout中,将wait重置为false并调用OnMouseSingleClick。最后,返回false,这样相同的超时就不会再次触发


我已经讨论这个问题好几天了,但在问了这个问题后不久,我找到了一个与你类似的答案。你给出了一个类似的答案,这确实验证了我自己的解决方案。谢谢你提供的额外细节!这就是我想到的:@fdpierson是的,您的代码使用了相同的总体思路。一个区别是,它还引入了响应双击之前的延迟,用户可能会注意到这一点。答案中的伪代码只为单次单击引入了延迟,需要区分真正的单次单击和双击的第一次单击。此外,最好从gtk读取gtk双击时间。设置,而不是硬编码为250ms。注意。另外,如果你想删除TimeOutHandler,你必须升级到GTK3,至少不要返回false。在MonoDevelop附带的GTK版本中,您不能以任何其他方式删除它们。我刚才必须升级。@fdpierson这太令人惊讶了。从文档中可以看出,GLib.Timeout.Add返回一个uint,您可以将其传递给GLib.Source.Remove。但是,即使无法删除超时处理程序,也可以使用处理程序可见的附加标志有效地禁用超时处理程序。