【问题标题】:Clearing mouse buffer in C#在 C# 中清除鼠标缓冲区
【发布时间】:2013-07-30 10:31:40
【问题描述】:

我在 winform 的代码隐藏文件中执行此操作时遇到问题:

// Waiting Cursor + disabling form
Cursor = Cursors.WaitCursor;
this.Enabled = false;

// Synchronous method
SomeWork();

// Re-enabling form
Cursor = Cursors.Default;
this.Enabled = true;

当前行为

例如在Somework() 期间单击按钮将在重新启用表单后执行与按钮关联的方法。

预期行为

我不希望表单在禁用表单时存储用户的点击事件。

问题

有没有办法清空表单的点击缓存(这样我会在重新启用表单之前这样做)?

重要编辑

一个可能的简单解决方案是在表单后面的代码中实现IMessageFilter 接口。使用 PreFilterMessage 禁用左侧似乎很容易:

public bool PreFilterMessage(ref Message m)
{
    // Blocks all the messages relating to the left mouse button.
    return (m.Msg >= 513 && m.Msg <= 515) ;
}

但再一次,禁用和重新启用鼠标左键不会清空鼠标缓冲区 ...

【问题讨论】:

  • 表单在禁用时无法接收任何点击消息。你确定吗?您能否提供有关您的演示的更多信息,例如您单击了哪个控件?...

标签: c# winforms caching mouseevent clicking


【解决方案1】:

问题是进程在同一个线程中运行,因此在进程开始运行之前表单实际上并没有被禁用。简单的做法是使用 Application.DoEvents() 强制它在启动进程之前将所有内容设置为禁用,但更专业(可能更安全)的方法是在另一个线程中运行耗时的进程。

注意:在我自己的编程中遇到另一个问题后,我发现您可能必须运行 Application.DoEvents() 才能再次启用所有内容 - 它会触发用户在禁用控件上所做的任何点击,而不是等待完成的过程 - 启用控件 - 然后触发点击。

显然 DoEvents 很乱,我应该使用线程。

【讨论】:

  • 如果不将 button.Enabled 属性设置为 false,它仍然会注册点击。上面的一小段代码禁用了我表单上的所有控件,它们不会注册点击。我把它放在运行一个长进程的按钮的点击事件中,就在进程运行之前,它完全按照你的要求工作......我在这个过程中点击了其他几个控件、按钮等,但什么也没有完成时发生。它到底有什么问题?在进程开始运行之前,您可能必须使用Application.DoEvents() 将控件设置为禁用。
  • DoEvents() 确实有效。但是很多cmets说这个方法很邪恶……
  • 您也可以在另一个线程中运行耗时的过程。 Application.DoEvents() 如果您以错误的方式使用它,可能会很危险。但它确实有一个目的。对此的最高评论是很好的阅读:stackoverflow.com/questions/5181777/use-of-application-doevents
  • 我编辑了我的答案。最初我的印象是您的表单实际上已设置为禁用,但控件没有。我的不好——我还没有在表单本身上使用 Enabled 属性,只是单独的控件,所以我不确定它做了什么。如果您在进程运行时禁用所有内容,则使用 Application.DoEvents() 可能非常安全。这就像使用 ShowDialog() 并从对话框表单运行进程一样。
  • 当然!事实上,在另一个线程中运行进程是最初的想法。后来,我发现线程解决方案不是最好的。那是因为该进程一次启动 4 / 5 个线程。所以我必须等待所有线程终止才能启动另一个最终用户进程。这绝对不容易处理。这就是为什么我认为如果表单冻结是个好主意..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-11
  • 1970-01-01
相关资源
最近更新 更多