开发者

User Inteface problem: A way to get MDI Children to show up in taskbar?

I'd like your advice on the following issue: We are studying different User Interface solutions for an Windows Forms application we are developing and we have come to the conclusion that the best solution seems to me a Single Document Interface the way MS Word does it: That is, each time we create a new document it will open in a new "main" window and the process is killed when all "main" windows are closed.

However, the way MS Excel approaches the MDI interface is also interesting and, due to the way our application works, it could be a good solution. The problem is that this solution seems to be more complicated due to one main reason: Showing MDI Child Forms in the task bar.

So my question is the following: can anybody give me some advice on how to get MDI Children to show up in the task bar. I'm almost certain there is absolutely no way to do it from the .NET Framework. 开发者_JAVA技巧I've been studying ways to go looking at the relevant Windows API but I don't seem to see an obvious way to try and get to what we want.

Thanks in advance.

EDIT

I forgot to mention app targets mainly Win XP platform.


You are right that there is no way to do this directly from C# as this functionality is not implemented in the .Net Fx, but rather in the Windows API. Luckily Microsoft provides a managed library to access these functions in Windows 7 (and some Windows Vista ones). Take a look at the Windows API Code Pack for Microsoft .Net Framework. The functionality you are looking for is called Tabbed Thumbnails.


By design, children of an MDI form do not show up in the Taskbar. It's best to stick to this principle.

On Windows 7, you can add a 'thumbnail' for an MDI child to the task bar but this functionality is not available directly in .net. You can check MSDN for the additional APIs.

There is a work-around, though: when selecting a form you can detach it from the MDI parent. You have to make sure that it is re-attached when a new child form is selected. Add the following code to your MDI container form:

    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;
        }
    }

I would not recommend this, however. Stick to the default behaviour, or look at the Windows 7 thumbnails if your app will run on Windows 7.


This is a bit of a hack, but works in XP. In Windows 7 it doesn't look too good, so you'd need to implement the tabbed thumbnails API instead.

Basically, it creates an invisible surrogate form for each MDI child control, and when a surrogate receives focus (when you select it in the task bar) it passes it on to the appropriate child window.

Assuming an MDI container named Form1, this code will do that:

    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();
        }
    }

Again, I don't think straying from the design is a good thing here. You're better off sticking to the MDI restrictions, and implementing the appropriate APIs on newer OS installations. If you really need the windows to show up in the task bar, then you can use a hack such as this.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜