窗体在调用其子窗体的 Hide 方法后失去焦点

Posted

技术标签:

【中文标题】窗体在调用其子窗体的 Hide 方法后失去焦点【英文标题】:Form loses focus after calling Hide method of its child form 【发布时间】:2009-12-11 13:49:40 【问题描述】:

我的应用程序中有 Form1 调用另一个表单 - Form2 使用 ShowDialog() 方法。在一些用户交互之后 Form2 调用它的 Hide() 方法。之后,我的应用程序有时会失去焦点,有时不会。这可能是一些设计错误。

代码提取:

    public class Form1 : Form
    
      Form2 form2;

      public void SomeMethod()
      
         if (form2==null) form2 = new Form2();
         DialogResult result = form2.ShowDialog(this);
      

    

    public class Form2 : Form
    
        public Form2()
       
           this.FormClosing += new FormClosingEventHandler(Form2_FormClosing);
       

       void Form2_FormClosing(object sender, FormClosingEventArgs e)
       
            if (e.CloseReason == CloseReason.UserClosing)
            
                e.Cancel = true;
                Hide();
            
       
    

编辑: 我的在线代码有错误

 DialogResult result = form2.ShowDialog(this);

曾经

DialogResult result = ShowDialog(form2,this);

【问题讨论】:

Form2_FormClosing 捕捉是什么意思? 我想让 form2 对象保持活力。但这并不重要。这只是说明问题的示例。它可以从另一个方法调用。 【参考方案1】:

如果您隐藏对话框,则 Form1 仍将无法访问,因为 ShowDialog 要求您在返回焦点之前将其关闭。

只有在你打算对它做某事时才处理 Form2 的关闭。否则只是让对话框关闭,隐藏它没有任何好处。

有关详细信息,请参阅 MSDN Form.ShowDialog。

代码示例

public class Form1: Form

     private Form2: form2;
     private bool doDbQuery;

     public Form1()
     
         doDbQuery = true;
     

     public void SomeMethod()
     
         if (form2 != null)
         
              form2 = new Form();
         

         if (doDbQuery)
         
             // do DB query
             // take a note of the information you retrieve
             doDbQuery = false;
         

         // pass this information to Form2 for it to display.
         DialogResult result = form2.Execute(...);
     


public class Form2 : Form    
        
    public Form2()       
    
    

    public DialogResult Execute(...)
    
        // use the execute method to inject the data you require for the form
        return ShowDialog;
    

【讨论】:

事实上我在对话框中的form2控件连接到数据库,加载它需要一些时间。这就是我隐藏它的原因。 如果您在关闭对话框时执行的过程很长,您应该考虑在 BackgroundWorker 上执行此操作,这样您就不会拖住 UI。 我在打开对话框时做了很长的过程,而且它总是一样的,所以没有必要每次打开对话框时都这样做。这就是为什么我隐藏对话框表单而不仅仅是关闭它的原因。 那么在这种情况下你应该改变你的代码。如果您打算隐藏表单,我不会调用 ShowDialog,因为您需要关闭对话框才能返回 Form1,只需调用 Show。另一种选择是设置一个标志,您可以在打开 Form2 时检查它,这将指示它是否应该执行您的数据库查询。 只调用 Show 工作正常,但它使父表单可访问。 ShowDialog 禁用它,直到子窗体被关闭或隐藏。【参考方案2】:
private: System::Void form_closing(System::Object^  sender, CancelEventArgs^ e) 
    MessageBox::Show( "Ulosteministeri Katainen" );
    e->Cancel = true;
    form->Hide();
    this->Focus();//this is the parent form

【讨论】:

【参考方案3】:

如果你使用一些“懒惰”的功能,你可以使用asynchronous methods,在你关闭你的表单(委托回调)的末尾。

【讨论】:

以上是关于窗体在调用其子窗体的 Hide 方法后失去焦点的主要内容,如果未能解决你的问题,请参考以下文章

如何让WPF中窗体失去焦点后TextBox中的被选中文本仍然保持高亮状态?

javascript脚本事件,窗体失去焦点事件怎么写,怎么触发事件????

C# Winform 控件或窗体失去焦点时,获取键盘输入数据(我用winform获取另一个窗口的数据)

C# 调用函数后窗体假死失去响应

当应用程序失去焦点时,Windows 窗体组合框会触发 SelectionChangeCommitted、SelectedValueChanged 和 SelectedIndexChanged 事件

对窗体操作的WM消息