【问题标题】:Cannot fire form activate event - issue with disabled forms无法触发表单激活事件 - 禁用表单的问题
【发布时间】:2017-09-13 06:37:52
【问题描述】:

我有一个派生自表单的类。在那个类中,我将 ShowDialog 事件隐藏在我自己的实现之后,该实现巧妙地禁用了所有其他表单,显示对话框,然后重新启用它们。它真的很好用。显示一个对话框,所有其他表单都显示为灰色。

问题是这样做会阻止 Activated 事件在焦点返回到调用表单时触发 - 我依赖于其他代码。

我假设激活的事件没有被触发,因为当焦点返回时,表单都被禁用了。为了解决这个问题,我尝试手动触发事件以激活表单

if (fParent != null) fParent.Activate();
  • 没用。

更复杂的是,在这种情况下,ParentForm 是一个 mdiChildForm,它的 Activated 事件是从父表单的 ActivatedMDIChild 事件中继而来的

有什么想法可以在这种情况下触发激活的事件吗?

    public DialogResult ShowDialog()
    {
        return setFormsToBackground(null);
    }

    public DialogResult ShowDialog(Form fParent)
    {
        return setFormsToBackground(fParent);
    }

    private DialogResult setFormsToBackground(Form fParent)
    {
        List<Form> lstFormsToEnable = new List<Form>();
        for (int i = Application.OpenForms.Count - 1; i >= 0; i--)
        {
            try
            {
                Form checkfrm = Application.OpenForms[i];
                if (checkfrm != this && checkfrm.Enabled)
                {
                    lstFormsToEnable.Add(checkfrm);
                    checkfrm.Enabled = false;
                }
            }
            catch (Exception ex)
            {

            }
        }
        DialogResult result = DialogResult.None;
        if (fParent == null) result = base.ShowDialog();
        else result = base.ShowDialog(fParent);
        for (int i = Application.OpenForms.Count - 1; i >= 0; i--)
        {
            try
            {
                Form checkfrm = Application.OpenForms[i];
                checkfrm.Enabled = true;
            }
            catch (Exception ex)
            {

            }
        }
        if (fParent != null) fParent.Activate();
        return result;
    }

【问题讨论】:

  • 没有repro,但这肯定很麻烦。大问题是您重新启用 Windows 为时已晚。在模态窗口关闭的那一刻,就在 ShowDialog() 返回之前,您的应用程序中没有可以激活的窗口。你把它们都禁用了。这可以为操作系统提供一个很好的理由来激活属于另一个进程的窗口。您必须在它完全关闭之前 执行此操作,因此您需要 FormClosing 事件。这很棘手,表单可能会取消它,所以最好让这些模式窗口实现一个接口。
  • 是的,我明白你的意思。在将对话显示为包装器之前创建一个虚拟表单,然后将重新激活代码放入其中,怎么样?或者这只是额外的不必要的开销。两个都可以试试,看看效果如何。

标签: c# winforms


【解决方案1】:

好的,感谢 Hans 让我走上正轨。问题确实涉及没有可激活窗口的表单堆栈。为了解决这个问题,我必须制作一个虚拟表单,以便始终可以使用某些东西来捕捉焦点——这比你想象的要棘手,因为你需要让它完全不可见并防止它出现在任务栏中。最终修改后的代码是这样的;

    private DialogResult setFormsToBackground(Form fParent)
    {
        Form dummyForm = new Form();
        dummyForm.ShowInTaskbar = false;
        dummyForm.FormBorderStyle = FormBorderStyle.None;
        dummyForm.Load += ((object sender, EventArgs e) => { (sender as Form).Size = new Size(0, 0); });

        List<Form> lstFormsToEnable = new List<Form>();
        for (int i = Application.OpenForms.Count - 1; i >= 0; i--)
        {
            try
            {
                Form checkfrm = Application.OpenForms[i];
                if (checkfrm != this && dummyForm != this && checkfrm.Enabled)
                {
                    lstFormsToEnable.Add(checkfrm);
                    checkfrm.Enabled = false;
                }
            }
            catch (Exception ex)
            {

            }
        }
        dummyForm.Show();
        DialogResult result = DialogResult.None;
        if (fParent == null) result = base.ShowDialog();
        else result = base.ShowDialog(fParent);
        for (int i = lstFormsToEnable.Count - 1; i >= 0; i--)
        {
            try
            {
                Form checkfrm = Application.OpenForms[i];
                checkfrm.Enabled = true;
            }
            catch (Exception ex)
            {

            }
        }
        dummyForm.Close();
        if (fParent != null) fParent.Focus();
        return result;
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 2014-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多