【问题标题】:Handle multiple hover to click events in C# for kinect在 C# 中为 kinect 处理多个悬停以单击事件
【发布时间】:2013-04-08 07:34:58
【问题描述】:

我正在用 C# 开发一个 Kinect 游戏,用户需要同时单击 2 个按钮,每只手悬停在一个按钮上。

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

为了解决这个问题,我正在考虑在处理第一次点击时对第二次点击进行排队。为此,我使用了以下基于this link的代码

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.Enqueue 的最佳重载方法匹配无效 论据。”

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

您对如何创建此按钮单击事件队列或处理来自用户的多次单击的其他方式有任何建议吗?

【问题讨论】:

    标签: c# multithreading queue kinect


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      您是否考虑过更底层的方法?首先想到的是创建两个热点区域而不是按钮,并监控用户的手是否同时在这些区域内。

      【讨论】:

        【解决方案3】:

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

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

        看看下面两个例子,它们使用“悬停点击”和“按下点击”交互

        在这两种情况下,您都在自定义控件上使用命中测试来处理事件。以下是我在其中一个应用中使用的命中测试功能示例:

        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 范例!不要试图将键盘/鼠标事件结构硬塞进一个基于手势的系统中——从长远来看,这只会给你带来更多的痛苦,并让你的用户感到困惑。

        【讨论】:

        • 非常感谢您的建议!我发现之前一直在编写代码的另一位程序员一直在使用相同的变量作为双手输入,这就是为什么我无法同时使用它们。我现在已经改变了这一点,以便双手由单独的变量处理。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多