【问题标题】:Messagebox is displayed multiple times消息框显示多次
【发布时间】:2012-10-09 12:40:13
【问题描述】:

我正在使用 Kinect 开发一个使用 C# 和 WPF 的图像查看应用程序。当用户将双手举过头顶时,我会显示Messagebox,询问用户他/她是否真的想退出:

    //Quit if both hands above head
    if (skeleton.Joints[JointType.HandLeft].Position.Y > skeleton.Joints[JointType.Head].Position.Y &&
        skeleton.Joints[JointType.HandRight].Position.Y > skeleton.Joints[JointType.Head].Position.Y)
    {
        pause = true;
        quit();
    }

quit()函数如下:

    private void quit()
    {
        MessageBoxButton button = MessageBoxButton.YesNo;
        MessageBoxImage image = MessageBoxImage.Warning;
        MessageBoxResult result = MessageBox.Show("Are you sure you want to quit?", "Close V'Me :(", button, image);
        if (result == MessageBoxResult.Yes) window.Close();
        else if (result == MessageBoxResult.No)
        {
            pause = false;
        }

    }

pause 变量用于在MessageBox 仍处于活动状态时停止识别任何手势。 (pause = false 表示手势识别有效,否则无效。)

所以有两个问题:

  1. MessageBox 显示两次。如果我在其中任何一个中单击Yeswindow 就会关闭。行为还可以,但我不想要两个窗口。

  2. 如果我单击No,则会显示另一个MessageBox。如果我在此框中单击No,则会打开另一个。这发生在我单击的每个连续的No 上。大约显示 5-6 次后,它给了我我想要的行为,即将pause 变量的值更改为false,从而激活其他手势的识别。

我到底做错了什么?我该怎么做才能停止一切并等待用户单击其中一个选项?还有为什么MessageBox 会显示多次(最初是两次,点击No 时会更多)?

【问题讨论】:

  • 这可能是因为 quit() 是同步的。因此,如果事件在代码处理 quit() 时发生,它可能会查询手在某处的事件。
  • 抱歉,我不知道什么是同步方法。不过问题已经解决了。谢谢你:)
  • @Kinected 你可以说它相似,但绝不是完全相同的重复。与提出该问题的人不同,我已经使用标志多次停止显示messagebox。我问这个问题的原因是,即使使用了一个标志,我也多次得到messagebox

标签: c# wpf kinect messagebox gestures


【解决方案1】:

如果不查看正在调试的代码很难判断,但我猜您的第一个代码块是在处理最新 Kinect 数据的某种循环或事件处理程序中调用的。

检查暂停

尝试在第一段代码上方添加类似这样的内容:

if (pause)
   return;

if (skeleton.Joints[JointType.HandLeft].Position.Y > skeleton.Joints[JointType.Head].Position.Y &&
    skeleton.Joints[JointType.HandRight].Position.Y > skeleton.Joints[JointType.Head].Position.Y)
{
    pause = true;
    quit();
}

超时

如果这不起作用,您可能需要添加自上次提示用户后的超时时间。

private void quit()
{
    if (DateTime.Now.Subtract(_lastQuitTime).TotalSeconds > 5)
    {

          //Prompt the user

          //Reset the timeout
          _lastQuitTime = DateTime.Now;
    }
}

【讨论】:

  • 你是对的。它在处理程序 (OnSkeletonFrameReady) 中使用,该处理程序检查 SkeletonFrame 是否准备就绪。您给出的第一个解决方案完美无缺!但我仍然不知道它发生了什么变化以及最初出了什么问题。
  • @KaranThakkar - 最初,您将 pause 设置为 true,但您没有使用该值来阻止再次显示对话框。
  • 那么让我直说吧。 return 所做的是,它脱离处理程序并再次进入处理程序?
  • return 退出当前方法。这与使用 if (!pause) { if (skeleton.Joints... } 将其余代码包装在该方法中相同
  • 同步是一种处理可以由多个线程访问的数据的技术(这就是您的示例中发生的情况)。多线程编程是一个非常深奥的话题。如果你想潜入那个兔子洞,一个不错的起点是MSDN Library。有关同步的详细信息,请参阅this topic
【解决方案2】:

在您的代码中,我看不到任何阻止两次调用 quit 方法的内容。只需在quit方法的开头设置一个全局变量为true,最后再设置为false,调用quit前检查是否为false。

【讨论】:

    【解决方案3】:

    我在猜测这段代码的工作原理,但试试这个:

    //Quit if both hands above head
    if (skeleton.Joints[JointType.HandLeft].Position.Y > skeleton.Joints[JointType.Head].Position.Y &&
        skeleton.Joints[JointType.HandRight].Position.Y > skeleton.Joints[JointType.Head].Position.Y &&
        !pause)
    {
        pause = true;
        quit();
    }
    else
    {
        pause = false;
    }
    
    ...
    
    private void quit()
    {
        MessageBoxButton button = MessageBoxButton.YesNo;
        MessageBoxImage image = MessageBoxImage.Warning;
        MessageBoxResult result = MessageBox.Show("Are you sure you want to quit?", "Close V'Me :(", button, image);
        if (result == MessageBoxResult.Yes) window.Close();
        else if (result == MessageBoxResult.No)
        {
            pause = false;
        }
    
    }
    

    【讨论】:

    • 我试过这个解决方案@KendallFrey,但它只会增加问题。现在我一次性获得所有这 5 到 6 个窗口,而不是以前的版本,我在单击 No 时获得每个新窗口。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多