在c#中处理多个悬停点击事件

本文关键字:悬停 事件 处理 | 更新日期: 2023-09-27 18:07:54

我正在用c#开发一款Kinect游戏,用户需要用两只手在一个按钮上悬停,同时点击两个按钮。

但是,在我当前的代码中,当用户将一只手悬停在按钮上时,其他按钮将被禁用,并且只有当第一只手停止悬停在按钮上时,另一只手才能单击。

为了解决这个问题,我正在考虑在处理第一次点击时排队进行第二次点击。为此,我基于这个链接

使用了以下代码
private Queue<System.Windows.Controls.Button> Button_Queue = new Queue<System.Windows.Controls.Button>();
private bool isProcessing = false;
private void Button_Click((object sender, RoutedEventArgs e){
if(isProcessing){
Button_Queue.Enqueue(this);
}
else
{
isProcessing = true;
// code here
isProcessing = false;
while(Button_Queue.Count > 0){
    Button_Queue.Dequeue().PerformClick();
}
}

但是,Button_Queue.Enqueue(this)行显示错误

" Queue的最佳重载方法匹配。队列无效参数。"

我猜这是因为按钮单击事件不能在用Button类型声明的队列中排队。

你有什么建议如何创建这个队列的按钮点击事件或另一种方式来处理从用户的多次点击?

在c#中处理多个悬停点击事件

您不需要将事件排队。如果isProcessing为真,则另一个按钮已被单击,因此您可以处理从该点开始的两个按钮单击事件。

您可以测量两次点击之间的时间,以确定它是否验证为"同时单击两个按钮"事件。

您考虑过更低级的方法吗?我想到的第一件事就是创建两个热点区域而不是按钮,并同时监控用户的手是否在这些区域内。

当你的手悬停在另一个对象上时,我不清楚为什么另一个按钮被禁用。在没有看到代码的情况下,我会说你正在做一些会导致这种情况的事情——而且没有理由这样做。

此外,你应该使用以手势系统为中心的交互概念,而不是为鼠标/键盘输入编写的东西。使用常规的UI对象,并以与传统输入并行的方式与它们交互,只会让用户感到困惑。

请看下面两个例子,它们使用了"悬停点击"answers"按下点击"交互

  • 基本交互,用于SDK 1.6
  • Control Basics, for SDK 1.7 (in Kinect for Windows Developer Toolkit)

在这两种情况下,您都是在自定义控件上使用命中测试来处理事件。下面是我在我的一个应用程序中使用的hit test函数的例子:

private void HitTestHand(HandPosition hand)
{
    // quick fix to null pointer exception on exit.
    if (Application.Current.MainWindow == null)
        return;
    Point pt = new Point(hand.X, hand.Y);
    IInputElement input = Application.Current.MainWindow.InputHitTest(pt);
    if (hand.CurrentElement != input)
    {
        var inputObject = input as DependencyObject;
        var currentObject = hand.CurrentElement as DependencyObject;
        // If the new input is a child of the current element then don't fire the leave event.
        // It will be fired later when the current input moves to the parent of the current element.
        if (hand.CurrentElement != null && Utility.IsElementChild(currentObject, inputObject) == false)
        {
            // Raise the HandLeaveEvent on the CurrentElement, which at this point is the previous element the hand was over.
            hand.CurrentElement.RaiseEvent(new HandInputEventArgs(HoverDwellButton.HandLeaveEvent, hand.CurrentElement, hand));
        }
        // If the current element is the parent of the new input element then don't
        // raise the entered event as it has already been fired.
        if (input != null && Utility.IsElementChild(inputObject, currentObject) == false)
        {
            input.RaiseEvent(new HandInputEventArgs(HoverDwellButton.HandEnterEvent, input, hand));
        }
        hand.CurrentElement = input;
    }
    else if (hand.CurrentElement != null)
    {
        hand.CurrentElement.RaiseEvent(new HandInputEventArgs(HoverDwellButton.HandMoveEvent, hand.CurrentElement, hand));
    }
}

注意,一个事件正在触发在手部光标下面的元素上。这些元素的例子可以在上面的两个链接中找到(HoverDwellButton是我在上面的代码示例中使用的)。

两个不同元素或同一元素上的两个事件可以在任何时候触发。你可以很容易地跟踪哪个用户在哪个按钮上,如果那个按钮正在被按下,或者如果它已经被按下。

这一切的关键是没有使用一个不是为手势系统设计的UI范例!不要试图将键盘/鼠标事件结构硬塞到基于手势的系统中——从长远来看,这只会给你带来更多的痛苦,并导致用户困惑。