如何防止拖动已禁用的表单

本文关键字:表单 何防止 拖动 | 更新日期: 2023-09-27 18:35:23

以下代码按预期工作,只是如果在禁用时"拖动"表单 - 当记事本退出时 - 表单将处于新位置。如何防止这种情况发生?

Enabled = false;
Process p = Process.Start("notepad");
p.WaitForExit();
Enabled = true;

如何防止拖动已禁用的表单

好的,我重现了这个问题。 问题是你在 UI 线程上调用 WaitForExit()。 这会阻止它抽取消息循环和处理输入事件。 它们将被放入消息队列中。 进程退出后,方法将返回,UI 线程将再次开始抽取消息。 并查找已缓冲的鼠标消息,并执行它们,因为窗口不再被禁用。

在 UI 线程上运行的代码的一般规则是它不应阻塞。 很多事情都会出错,这只是一个例子。 使用 Process 类很容易做到,它有一个在进程退出时触发的事件。 所以你不需要使用 WaitForExit()。 使代码如下所示:

        this.Enabled = false;
        var prc = System.Diagnostics.Process.Start("notepad.exe");
        prc.EnableRaisingEvents = true;
        prc.SynchronizingObject = this;
        prc.Exited += delegate { 
            this.Enabled = true;
            this.Activate();
        };

请注意,激活() 调用是将窗口放回前台所必需的。 这可能并不总是有效。

您可以尝试从第二个使用 showDialog 调用的窗体运行 Process start。

Form2 frm2 =new Form2();

FRM2.显示对话框();

在 Form2 加载事件中,将您的

Process p = Process.Start("notepad");
p.WaitForExit();
this.DialogResult=DialogResult.OK;

必须检查语法,它可能并不完美。

您甚至可以将 Form2.Visible 设置为 false,这样用户甚至永远不会看到它。

编辑 如HomeToast建议的那样,这效果很好,只要您不介意隐藏表单,如果您想保持表单可见,我会选择我的第一个建议

在此选项中,我们将主窗体 Visible=false 代替,如果 Enable=false如果没有要拖动的窗体,则用户无法拖动它。

this.Visible = false;
Process p = Process.Start("notepad");
p.WaitForExit();
this.Visible = true;