views:

199

answers:

2

I'm maintaining a Windows CE app built with the .NET Framework that has about 45 forms. There are 5 'sections' which lead to the function you want. The application is 100% full screen and it is important that it can't be minimized.

Since there are so many forms, it's difficult to keep track of which form should be displayed after one is closed. For this, I'm setting the form owner property before showing it, and showing the owner when closing it.

I've also been advised that it is best to instantiate all forms when the application loads, and not dispose them to save processing time. I'm not sure about this.

My question is, what is the best way to go about showing, hiding forms where you want any 1 form to be in front, full screen all time?

+2  A: 

There are a whole load of variables to the process, so there's no one-size-fits-all methodology. Sure, loading all Forms initially means that inter-page navigation is fast, but it make load slower and it can also run you out of memory.

My general methodology is to use a framework - personally I'm a fan of the OpenNETCF IoC framework, but then I'm probably biased.

In any event, you need a general framework that does two things:

  1. Separates the Views from the Model (whether those Views should be FOrms, User CFontrols, Panels or whatever is fully debatable).
  2. Tracks what View is at the fore and which View should be "next" (whether you're moving formaward or back)

I did a simple framework article on this ages ago for MSDN. I updated it to use a more pure MVC separate and the IoC framework more recently.

This is not to say that my way is the only way, or even the "right" way. It is, however, a methodology that I've found to be successful in multiple deployments, both on the desktop and on devices.

It's difficult to give you more fine-grained suggestions than that becasue we really have no idea what your requirements or limitations are. If you're running on a slow ARM device with very limited memory and loads of graphics I'd certainly attack some things differently (caching, lazy loading, etc) than an pentium-class x86 embedded appliance with a gig of RAM.

EDIT

You'll see that the difference between how MusiGenesis and I would attack this highlights the fact that there is no "right" way. As we speak I'm doing code for a full-screen embedded app that has 47 views and the project contains one and only one Form. He would likely use 47 different Forms. Both get the job done. The commonality is that we both have some form of underlying infrastructure that deals with all of the goo required to know what's supposed to be on top. He relies on ShowDialog popping down the native z-order of Forms. I rely on a custom framework that remembers where you came from.

Again, this only highlights that there is no right or wrong - as long as it meets the project requirements.

ctacke
Actually, *I* would do it your way if I were starting from scratch. My method is a hack that is sure to break with some new version of Windows Mobile (assuming there will be new versions). It might be a little easier for a newbie to do, though, since it's more like regular Windows programming (if that's a good thing).
MusiGenesis
+2  A: 

I would not go the route of instantiating 45 forms when the application starts. This would severely lengthen the startup time and possibly (if not probably) exhaust your memory resources, all to provide functionality that your user may not even need.

In my WinMo applications, each form is designed to work with a relatively small subset of data, so the startup time is limited to database calls and loading the data into the form's controls. Typically, the time required to instantiate one of these forms and show it is never more than a second or two.

If your forms are taking longer than this to show, it's possible that there's a problem with your data retrieval or with the way the data is loaded into the form's controls (e.g. you might have a custom gridview control that fully renders all 300 rows even though only 12 are visible at one time). If your data is so large that it legitimately takes a long time to retrieve, chances are that's far more data than a user can practically interact with anyway.

I assume your mention of "5 sections" to get where the user needs to go means that they might (at a maximum) be "drilling down" 5 levels to something. If you implemented this by having each form instantiate and show the next form using ShowDialog, you would have at most 5-6 forms in existence at any one time, which shouldn't be any problem for a .Net CF application (I do this all the time). This way, you don't have to do anything special to keep track of which form should be shown when - you just open a form from wherever, and when the form is closed you're automatically back to the calling form.

There is some z-order/task manager weirdness that you have to deal with, but it's not especially complicated. Before calling ShowDialog on the child form, you set the parent form's Text property to a blank string, and then set it back to the form's original caption after ShowDialog returns. This isn't strictly necessary, but in Windows Mobile (at least up to version 6) all open .Net forms (with a non-blank Text property) show up in the Running Programs list, even if they're all from the same application. I generally like my multi-form applications to appear to be just one program, so I usually set the Text of every form to the name of the application).

I've also experimented with a single-form application that implements every piece of UI as a UserControl instead of a Form, and then creates and stacks the controls as if you were creating and opening forms. This works but it's a hack and I don't recommend it. Forms have a Load event and UserControls don't, which is the main problem.

MusiGenesis
Ah, but if you use a framework around those UserControls, you get to create your own Load event.
ctacke
Bah, I don't even use *controls* any more - I just `BitBlt` to the Screen. :)
MusiGenesis
Oh, I have one Form with 47 UserControls for Views. But the interesting thing is I have a single custom control that is used to display *every* UI element on every view. Basically to get the required alphablending I needed I just made a "swiss army knife" control, blended it with custom painting and abandoned everything else in the toolbox. Ah the joys of CF development.
ctacke