【问题标题】:ModifierKeys "sticky" bug when used with FileSystemWatcher与 FileSystemWatcher 一起使用时修饰键“粘滞”错误
【发布时间】:2013-09-25 01:30:00
【问题描述】:

我在 this threadthis threadFileSystemWatcher here 中了解了 Control.ModifierKeys 以及 FileSystemWatcher 特定的解决方法 here。但是,当我将两者结合起来时,我遇到了一个奇怪但可以解释的错误。至少,我有一个假设。

我的表单使用FileSystemWatcher 来检测对文件的更改并在触发时运行某些内容。但是,它运行的东西有点分散注意力和浪费时间,所以如果保存是由 Ctrl+S 完成的,我试图让它跳过运行,即当按住 Control 键时。

代码是这样的:

private void onFileChanged(object source, FileSystemEventArgs e)
{
    // The try/finally blocks prevent double raising of the changed event
    try
    {
        myFileWatcher.EnableRaisingEvents = false;
        if ((ModifierKeys & Keys.Control) != 0)
            MessageBox.Show("Control held down!");
        else
        {
            MessageBox.Show("Running stuff!");
        }
    }
    finally
    {
        myFileWatcher.EnableRaisingEvents = true;
    }
}

这一切都很好,注意到两个MessageBox.Show 调用替换了块内代码。在正常使用情况下,它可以工作。但是,文件的保存和onFileChanged的触发之间有一个非常小的时间延迟。如果在onFileChanged 触发之前释放 Ctrl 键,即如果您非常快速地点击 Ctrl+S,则会产生非常奇怪的行为。一方面,显然没有检测到 Control 键,但是从这里开始,即使您在 Ctrl+S 之后按住 Control 直到弹出窗口显示,ModifierKeys 仍然会为 0,它会认为 Ctrl 没有被按住。然后,如果您按住 Ctrl 的同时单击弹出窗口中的 OK,即使您转到 File->Save 在它正在观看的文件中,ModifierKeys 也会突然触发 Control 键。

有没有办法解决这个错误,或者我是否必须将它标记为无法修复并告诉我的用户按住 Control 键的时间比他们平时更长的时间才能避免这个错误?

【问题讨论】:

  • 您的意思是用户在另一个应用程序(如记事本)中编辑文件并按 Ctrl-S 保存?
  • 是的,就是这样。应用程序处理正在观看的文件,然后运行几个进程,这些进程会弹出窗口,每个进程需要几秒钟才能完成,因此,如果您正在编辑并不停地按 Ctrl+S 保存以避免丢失工作,您可以想象一下这会很快变得烦人。
  • @KevinT 不太明白您为什么要检测Ctrl,如果您想确定应用了什么样的更改,您可能需要查看e.ChangeTypeFileSystemEventHandler
  • 在编辑文件时,您经常按 Ctrl+S,这是一种保存更改并避免丢失工作的方法。每次这样做都重新处理文件会适得其反。更改类型无济于事,因为我试图检测文件是通过键盘快捷键保存还是通过文件菜单保存。
  • @KevinT 您尝试通过File menu 检测保存的内容是什么?顺便说一句,我必须补充一点,我们还有 1 种方式 来保存文件,我经常使用这种方式,这只是 先关闭编辑器窗口然后在出现要求保存更改以接受保存的对话框上单击确定

标签: c# windows winforms keyboard listener


【解决方案1】:

我会尝试设置 a global keyboard hook 并记录是否仍然按下 Ctrl+S 或在触发 filewatcher 事件之前的一定时间内按下。

【讨论】:

  • 我不认为它会起作用,因为 Stephen Toub 用于检查修饰键的解决方案回退到修饰键,如 cmets 所示:Mladen 2006 年 5 月 10 日下午 1:04 # 好东西!我想知道您将如何检查 CTRL+V 或 CTRL+ALT+k 或类似的组合?谢谢。 Stephen Toub - MSFT 2006 年 5 月 10 日下午 5:41 # System.Windows.Forms.Control.ModifierKeys 应该可以解决问题,告诉您是否按下了 shift、alt 和/或 control。
  • @KevinT ModifierKeys 很有用,但重点是您必须知道何时在代码中使用它?使用global key hook 将捕捉到按键被按下的确切时间,并相应地执行一些检查和编码。我怀疑global key hook 可能是更新ModifierKeys 的内部实现
  • 嗯,如果你坚持,我明天再看一遍。不过,我并不完全相信它会起作用。当然,我可能是错的,因为我对 C# 还比较陌生。
  • 好吧,我意识到它不再是“明天”了,但我终于有机会真正尝试一下并破解它,它解决了问题!谢谢 ChrisWue!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-23
相关资源
最近更新 更多