【问题标题】:How Can I open a Winform Dialog when closing another?关闭另一个对话框时如何打开 Winform 对话框?
【发布时间】:2009-10-05 18:03:11
【问题描述】:

我有一个对话框,显示有关对象的一些信息。我想关闭此对话框以显示相同的对话框,但现在使用对象的兄弟。这是一个复杂的对话框,根据分配的对象加载不同的组件,我不能只更改对另一个对象的引用 我尝试在 Closed 事件中启动新的,但前者并没有从屏幕上消失并一直显示。还尝试了一种在对话框中调用的静态方法,将相同的对话框作为参数传递,因此它关闭对话框“dialog.Close()”并打开一个新对象并显示新对象。但前一个仍然在后面保持开放。 有没有办法做到这一点,关闭第一个窗口并打开第二个窗口?

(这是静态方法,参数传递的窗口在新创建的窗口关闭之前不会关闭)

// From the Dialog try to launch the second one closing this.
private void btnSibling_Click(object sender, EventArgs e)
        {
                SwitchToSibling(this);
        }

private static void SwitchToSibling(SiblingDialog window)
        {
            try
            {
                double id = 0;
                id = window.SelectedSibling();
                if (id != 0)
                {
                    // Get's the same Parent so to the new Dialog
                    Control owner = window.Owner;
                    window.Close();
                    Sibling sibling= Sibling.Get(id);
                    SiblingDialog.ShowSibling(sibling, false, owner);
                }
            }
            catch (GroupException ex)
            {
                MessageBox.Show(ex.Message);
            }

        }

【问题讨论】:

  • 所涉及的对话框是模态的还是非模态的?

标签: c# winforms


【解决方案1】:

我遇到了同样的问题,经过大量故障排除后,我设法以完全不同的方式解决了它:我首先等待 Forms.Application.LeaveThreadModal 事件发生,然后等待下一个 Forms.Application .Idle 事件发生。到那时第一个对话框已经完全消失了,所以可以毫无问题地启动第二个对话框。

只等待空闲事件,或只等待离开线程模式事件,或以相反顺序等待两个事件,将不起作用。

注意:仅等待空闲事件 APPEARS 起作用,但只要通过用鼠标单击第一个对话框的按钮来激活第二个对话框即可。如果您通过按下键盘上该按钮的助记键来触发该按钮,则第二个对话框将出现在第一个对话框的上方!你必须按照我描述的顺序来避免这种情况!

再想一想,在我看来我的解决方案有点“神奇”,这意味着它可能会在 dotnet 框架的未来版本中停止工作,所以我想我会放弃它并遵循Mike Hoffer 的建议,据我所知,这与 jmayor 为自己给出的答案基本相同并标记为已接受。 (事实上​​,Mike Hoffer 的回答有点难以理解。)

【讨论】:

    【解决方案2】:

    如果不知道 SiblingSiblingDialog 类中的细节,当然可以。唯一的限制是,如果您关闭作为应用程序主窗口的窗口,应用程序将退出。

    例如,您可以提供如下方法:

    private static void CloseAndShow(Form formToClose, Form formToShow)
    {
        formToClose.Close();
        formToShow.Show();
    }
    

    这将关闭formToClose 并显示formToShow

    【讨论】:

    • 这与我在静态方法中所做的几乎相同,我正在关闭一个对话框并显示新的对话框。当我在第一个对话框中调用此方法时,它不会在执行该方法时关闭,而是在函数(调用 Close() 方法的位置)结束时关闭。似乎 Dispose 或其他释放资源的方法仅在方法结束后调用。
    【解决方案3】:

    如果你已经为第一个对话框设置了所有者,并且你知道它的类型,你应该可以解决这个问题:

    • 在对话框的 所有者。
    • 当用户点击关闭时 按钮,调用事件。
    • 不要 通过按钮关闭对话框。

    • 让拥有的窗口关闭 事件处理程序时的对话框 调用。然后有拥有对话框 显示同级对话框。

    【讨论】:

      【解决方案4】:

      Fredrik Mork's answer 的扩展,解决了关闭表单可能是控制程序退出状态的表单这一事实。

      private static void CloseAndShow(Form formToClose, Form formToShow)
      {
          Application.Run(formToShow);
          formToClose.Close();
          formToShow.Show();
      }
      

      Application.Run 告诉程序在传递给它的表单关闭时退出

      【讨论】:

        【解决方案5】:

        您似乎正在设置对话框的所有者,您可以尝试在 MyForm 类的 FormClosed() 事件处理程序中使用 owner.BeginInvoke()。 :

        public partial class MyForm : Form
        {
            static int count = 0;
            public MyForm()
            {
                InitializeComponent();
            }
        
            private void button1_Click(object sender, EventArgs e)
            {
                this.Close();
            }
        
            public static void ShowMyDialog(MyForm form, IWin32Window owner)
            {
                count++;
                form.Text = "My ID: " + count;
                form.ShowDialog(owner);
            }
        
            delegate void MyDel(MyForm form, IWin32Window owner);
        
            private void MyForm_FormClosed(object sender, FormClosedEventArgs e)
            {
                MyDel del = ShowMyDialog;
                MyForm mySecondForm = new MyForm();
                this.Owner.BeginInvoke(del, mySecondForm, this.Owner);
            }
        }
        

        【讨论】:

          【解决方案6】:

          我能找到解决办法的唯一方法是从静态方法调用我的对话框(使用某种单例模式),然后使用静态变量来标记何时需要重新打开对话框。因此,当在静态方法中结束对话执行时,它会检查是否需要重新打开。 否则我看不到可能的方法。

          【讨论】:

            猜你喜欢
            • 2015-12-30
            • 2012-11-10
            • 1970-01-01
            • 2020-11-23
            • 1970-01-01
            • 2015-12-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多