【问题标题】:How to prevent a disabled Form from being dragged?如何防止禁用的表单被拖动?
【发布时间】:2012-05-31 00:06:47
【问题描述】:

以下代码按预期工作,但如果在禁用时“拖动”表单(当记事本退出时),表单将位于新位置。如何预防?

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

【问题讨论】:

  • 这个问题/答案或许能帮到你:stackoverflow.com/questions/907830/…
  • @MAV 谢谢。但我想知道是否有一些直接的方法,比如某种类型的“完整”禁用表单(或一些 simple 刷新事件队列)。
  • @ispiro,据我所知,在 MAV 的链接问题中捕获 WndProc 消息并过滤掉“MOVE”命令几乎是最直接的。我不知道您是否也想盲目地刷新表单消息队列。
  • 在表单被禁用的情况下你是如何设法拖动窗口的很难猜到。 “Exists”也很难理解,应该是“exists”吗?改进您的问题。
  • @HansPassant 看看我的回答,我们在那里进行了一些讨论,他所说的确实正在发生,我猜这是一个错误。如果您在禁用时拖动 Form1,或者正在发生 Form.ShowDialog,当您通过启用它返回到第一个窗体或 Form2 返回一个对话框结果时,第一个窗体将移动到您尝试拖动它的位置。奇怪但真实。

标签: c# .net winforms


【解决方案1】:

好的,我重现这个问题。问题是您在 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();
        };

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

【讨论】:

  • 我也喜欢,我爱学习!!
【解决方案2】:

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

Form2 frm2 =new Form2();

frm2.ShowDialog();

在 Form2 Load 事件中放置你的

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

必须检查所有可能不完美的语法。

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

EDIT 正如 HomeToast 所建议的那样,只要您不介意隐藏您的表单,这非常有效,如果您想保持您的表单可见,我会采用我的第一个建议

在此选项中,我们将主窗体 Visible=false,而不是如果 Enable=false 如果没有要拖动的窗体,则用户不能拖动它。

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

【讨论】:

  • 我对此进行了测试,它工作正常,除了当您关闭记事本时,它会按预期关闭 Form2,但 Form1 似乎最小化。
  • 其实我从来没想过,本来是想隐藏Form2,但是你建议隐藏Form1,然后用户可以注意修改。我会将其添加为编辑,尽管@hometoast 你值得称赞。
  • 哈哈。不是我的想法,您在编辑前的最后一句话是:“您甚至可以将 Form2.Visible 设置为 false,因此用户甚至看不到它。”但是谢谢
  • 感谢您的回答。好想这个主意。不幸的是,它不起作用。
  • 它似乎对您有用(并最小化原始表单)的原因是因为 Visual Studio 会以某种方式干扰它。尝试以下操作:开始调试后 - 全部最小化 -> 显示正在运行的表单 ->(打开记事本)-> “拖动”表单 -> 关闭记事本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-11
  • 2022-07-15
  • 2016-06-30
  • 1970-01-01
相关资源
最近更新 更多