none
MDI forms in Compact framework applications

    Question

  • Hello

    Can someone please tell me if it is possible to create MDI forms application using compact framework?

    I know that the compact framework form does not have MDI Parent property and have seen some work arounds for creating MDI forms applications. Basically this involves setting the parent property of a child form to the main form but this approach doesnt work when the application is run on the desktop although it works on emulator and WinCE device.

    Any ideas???

    Thanks
    Durgesh.
    Monday, December 31, 2007 5:09 AM

Answers

  • Durgesh:

     

    There is no direct support for this functionality in CF, but you can emulate this if you're willing to do the extra work.  As you already know, this will not work in Pocket PC / Windows Mobile because of the fact that all forms are displayed as full-screen.  But, on WinCE you can control the size / position of all forms within the screen's client area.

     

    We have a warehouse application that runs on Symbol scanners (WinCE v5.0) that uses a MDI we created.  Instead of using Form.ShowDialog() you would use the Form.Show() method instead (because ShowDialog() is a blocking call and this obviously would not work correctly).  You'll have to track which forms are open and handle them the same way a regular desktop MDI would work.

     

    Especially important is to make sure you call Dipose() on each child form when the user is done with it.  The ShowDialog() handles this automatically, but Show() does not .... even though you are working with these forms (and other GUI items) in managed code, the underlying native objects, which are effectively "wrapped" by the managed code, will not get correctly cleaned up unless the Dispose() method get's called.  This is an issue for many developers, and thus they end up with memory leaks and performance problems.  Since you will probably have a click event (or some other similar technique for launching a particular MDI child form) you will store the reference in your "active forms list" within your main "MDI" form (so you can track which forms are open if the MDI is shutting down .... which would mean you need to shut down all the children).  Depending upon your desired functionality, you might also want to use the Activated / Deactivated event handlers too. 

     

    The easiest way to ensure the child form's Dispose() method is called when the user is done with it is to simply register for the Closed event on the child form (not the Closing event, but the Closed event) when you are creating the form and calling the child form's Show() method.  Then when the child has fired the Closed event your event handler will call the Dispose() method on that object, thus ensuring the native objects get disposed of correctly too.

     

    Example:

     

    MDIParentForm code ...............................

     

    private void OpenSelectedChildForm()

    {

    MDIChildForm child1 = new MDIChildForm();

    child1.Closed += new EventHandler(MDIChildrenCleanup);

    child1.Show();

    }

     

    private void MDIChildrenCleanup(object sender, EventArgs e)

    {

    ((Form)sender).Dispose();

    }

     

     

    Not a big deal, but this is a way to help yourself on the memory / performance issue. 

     

    As most people would correctly point out, "perhaps you need to redesign your UI" if you are looking for MDI on a hand-held device??  But, if you decide this is correct way to go you can do it by tracking in a list which children are opened, ensuring they get cleaned up correctly, and managing the size / location of the children ..... this will give you MDI emulation on Windows CE.

     

    This isn't a complete example (or, an exhaustive discussion on some of the other issues) on MDI emulation but I think you get the idea.

     

    Good luck.

    Wednesday, January 02, 2008 5:35 PM

All replies

  • I will go out on a limb here and say that I have yet to see a PocketPC application that needs to be MDI.

     

    Perhaps you can redesign your paradigm, if not please post your concept so that we may help you further.

     

    Monday, December 31, 2007 2:56 PM
  • Hi Stephen

    This application is not for Pocket PC, it's for a WinCe touch screen device. This application basically needs to have a MDI interface. What happens when I set the Parent property of the Child form to the Parent form is that I get an exception when I run the application on my PC stating that a top level control i.e. Form cannot be added to the control collection of the Form (Parent form). However this same application runs on the WinCe emulator and the device.

    I was wondering if there was a workaround to make the application run on both systems.

    The problem is complicated further by the fact that compact framework does not support the MDI container property for forms.

    Thanks.
    Durgesh
    Tuesday, January 01, 2008 8:08 AM
  •  

    I don't think there're any workarounds exist. As Stephen said you should consider rethinking the design. If you can explain what you are trying to achive may be somebody will be able to suggest a solution for you.
    Wednesday, January 02, 2008 2:08 AM
  • OK, WinCE touch or PPC does not really matter, MDI is just not a good idea for the OS.

     

    If you really NEED / WANT MDI application then I suggest you look into using XP Embedded or something like that.

     

    Once again I will offer to help with your design issue that makes an MDI required.

     

    Also, you could create your own MDI container if it is absolutely necessary

     

     

    Wednesday, January 02, 2008 1:45 PM
  • Durgesh:

     

    There is no direct support for this functionality in CF, but you can emulate this if you're willing to do the extra work.  As you already know, this will not work in Pocket PC / Windows Mobile because of the fact that all forms are displayed as full-screen.  But, on WinCE you can control the size / position of all forms within the screen's client area.

     

    We have a warehouse application that runs on Symbol scanners (WinCE v5.0) that uses a MDI we created.  Instead of using Form.ShowDialog() you would use the Form.Show() method instead (because ShowDialog() is a blocking call and this obviously would not work correctly).  You'll have to track which forms are open and handle them the same way a regular desktop MDI would work.

     

    Especially important is to make sure you call Dipose() on each child form when the user is done with it.  The ShowDialog() handles this automatically, but Show() does not .... even though you are working with these forms (and other GUI items) in managed code, the underlying native objects, which are effectively "wrapped" by the managed code, will not get correctly cleaned up unless the Dispose() method get's called.  This is an issue for many developers, and thus they end up with memory leaks and performance problems.  Since you will probably have a click event (or some other similar technique for launching a particular MDI child form) you will store the reference in your "active forms list" within your main "MDI" form (so you can track which forms are open if the MDI is shutting down .... which would mean you need to shut down all the children).  Depending upon your desired functionality, you might also want to use the Activated / Deactivated event handlers too. 

     

    The easiest way to ensure the child form's Dispose() method is called when the user is done with it is to simply register for the Closed event on the child form (not the Closing event, but the Closed event) when you are creating the form and calling the child form's Show() method.  Then when the child has fired the Closed event your event handler will call the Dispose() method on that object, thus ensuring the native objects get disposed of correctly too.

     

    Example:

     

    MDIParentForm code ...............................

     

    private void OpenSelectedChildForm()

    {

    MDIChildForm child1 = new MDIChildForm();

    child1.Closed += new EventHandler(MDIChildrenCleanup);

    child1.Show();

    }

     

    private void MDIChildrenCleanup(object sender, EventArgs e)

    {

    ((Form)sender).Dispose();

    }

     

     

    Not a big deal, but this is a way to help yourself on the memory / performance issue. 

     

    As most people would correctly point out, "perhaps you need to redesign your UI" if you are looking for MDI on a hand-held device??  But, if you decide this is correct way to go you can do it by tracking in a list which children are opened, ensuring they get cleaned up correctly, and managing the size / location of the children ..... this will give you MDI emulation on Windows CE.

     

    This isn't a complete example (or, an exhaustive discussion on some of the other issues) on MDI emulation but I think you get the idea.

     

    Good luck.

    Wednesday, January 02, 2008 5:35 PM
  • Thanks Mark! That does help a lot.
    Friday, January 04, 2008 6:02 AM