用户界面问题:让MDI孩子出现在任务栏中的一种方法?

时间:2011-05-29 10:20:57

标签: c# user-interface

我希望您对以下问题提出建议:我们正在研究我们正在开发的Windows窗体应用程序的不同用户界面解决方案,我们得出的结论是,最佳解决方案在我看来是单文档接口的方式。 Word这样做:也就是说,每次我们创建一个新文档时,它将在一个新的“主”窗口中打开,当所有“主”窗口关闭时,该过程将被终止。

然而,MS Excel接近MDI接口的方式也很有趣,由于我们的应用程序的工作方式,它可能是一个很好的解决方案。问题是这个解决方案似乎更复杂,原因有一个:在任务栏中显示MDI子窗体。

所以我的问题如下:任何人都可以就如何让MDI孩子出现在任务栏中给我一些建议。我几乎可以肯定,从.NET Framework中绝对没有办法做到这一点。我一直在研究如何查看相关的Windows API,但我似乎没有看到一种明显的方法来尝试达到我们想要的效果。

提前致谢。

修改

我忘了提到app目标主要是Win XP平台。

3 个答案:

答案 0 :(得分:2)

你是对的,没有办法直接从C#执行此操作,因为此功能未在.Net Fx中实现,而是在Windows API中实现。幸运的是,Microsoft提供了一个托管库来访问Windows 7(以及一些Windows Vista)中的这些功能。看看Windows API Code Pack for Microsoft .Net Framework。您正在寻找的功能称为选项卡式缩略图

答案 1 :(得分:1)

按照设计,MDI表单的子项不会显示在任务栏中。最好坚持这个原则。

在Windows 7上,您可以将MDI子项的“缩略图”添加到任务栏,但此功能无法直接在.net中使用。您可以在MSDN上查看其他API。

但是有一种解决方法:在选择表单时,您可以将其从MDI父级中分离出来。选择新的子表单时,必须确保重新附加它。将以下代码添加到MDI容器表单中:

    private Form focusedChild;

    private void CreateWindow()
    {
        Form window = new Form();
        window.GotFocus += new EventHandler(Child_GotFocus);
        window.Show();
    }

    void Child_GotFocus(object sender, EventArgs e)
    {
        Form window = sender as Form;

        if (null != window)
        {
            if (focusedChild != null && window!=focusedChild)
            {
                focusedChild.SuspendLayout();
                focusedChild.MdiParent = null;
                focusedChild.WindowState = FormWindowState.Minimized;
                focusedChild.ResumeLayout();
            }


            window.SuspendLayout();
            window.MdiParent = this;
            window.WindowState = FormWindowState.Maximized;
            window.ResumeLayout();

            focusedChild = window;
        }
    }
但是,我不建议这样做。坚持默认行为,或者如果您的应用程序将在Windows 7上运行,请查看Windows 7缩略图。

答案 2 :(得分:1)

这有点像黑客,但在XP中有效。在Windows 7中,它看起来不太好,因此您需要实现选项卡式缩略图API。

基本上,它为每个MDI子控件创建一个不可见的代理表单,当代理获得焦点时(当您在任务栏中选择它时),它会将其传递给相应的子窗口。

假设一个名为Form1的MDI容器,此代码将执行此操作:

    private void Form1_Load(object sender, EventArgs e)
    {
        CreateWindow("child 1");
        CreateWindow("child 2");
    }

    private void CreateWindow(string name)
    {
        Form window = new Form();
        window.MdiParent = this;
        window.Text = name;
        window.Show();

        Form surrogate = new Form();
        surrogate.FormBorderStyle = FormBorderStyle.None;
        surrogate.Text = name;
        surrogate.Show(this);
        surrogate.Size = Size.Empty;
        surrogate.GotFocus += new EventHandler(surrogate_GotFocus);

        surrogate.Tag = window;
        window.Tag = surrogate;
    }

    void surrogate_GotFocus(object sender, EventArgs e)
    {
        Form surrogate = sender as Form;
        if (null != surrogate && null != surrogate.Tag)
        {
            Form target = surrogate.Tag as Form;
            target.Focus();
        }
    }

同样,我不认为偏离设计是件好事。您最好坚持MDI限制,并在较新的OS安装上实施适当的API。如果你真的需要在任务栏中显示窗口,那么你可以使用这样的黑客。