|
Chapter 4: Building Windows Forms Applications
4 Building Windows Forms ApplicationsAlthough we have seen that building a Windows form and its associated code for the .NET Compact Framework is very similar to the way it is done in the full .NET Framework, the design of the form is very different. This is especially true for Pocket PC applications. Whereas Windows CE is designed to emulate the look and feel of the Windows desktop, the Pocket PC operating platform is designed with a smaller form factor, a touch screen, and a stylus input.This means that when you design an application that targets the Pocket PC platform or any Windows CE device with limited screen size, you should plan the number, size, and layout of the controls for each form. An example application, DVD Catalog, will be used throughout this chapter to illustrate the points that are being made. The full DVD Catalog application is available with this book's sample files.
Working with FormsThe Form class you use in a Windows CE project and the one you use in a Pocket PC project are identical; they have the same properties, methods, and events. However, the values of some of the properties will depend on the physical device the application is targeting. The maximum height and width of the form will be determined by the physical size of the device the form will be used on. When certain properties of the form are set, the behavior of the form varies depending on whether the form is part of a Windows CE project or a Pocket PC project.
Setting Properties of the Form ClassThe values that control the form's border style, as well as the ones that control the appearance of the form's control box and the form's minimize, maximize, and close buttons, differ between a Windows CE project and a Pocket PC project. This section discusses setting properties that relate to the form's appearance and how those settings affect the form depending on the target platform.
In a Pocket PC project, setting the property to FormBorderStyle.None creates a form with no border and no caption. The form can be moved and resized using code. Setting the property to any other value will cause the form to expand to fill the desktop area and will prevent the form from being moved or resized. The desktop area is the entire screen minus the Start menu bar and the main menu bar of the application, if present. In a Windows CE project, setting the property to FormBorderStyle.None or FormBorderStyle.FixedDialog creates a form with no border or caption. The form can be resized and moved using code but not by the user. All other settings create a form with a border and a caption that can be moved using code or by the user, but the form can be resized only using code.
In a Pocket PC project, the form will fill the desktop area when its WindowState property is set to FormWindowState.Normal. Setting the property to FormWindowState.Maximized will make the form fill the entire screen, obscuring the Start menu bar while still displaying the form's main menu if one is present. In a Windows CE project, setting the WindowState property to FormWindowState.Normal will cause the form to display according to the Size property. Setting the form to FormWindowState.Maximized will cause the form to expand to fill the entire desktop area.
Keeping to Form Display GuidelinesPocket PC user interface guidelines recommend that all forms should always be the full size of the desktop area (the full screen, excluding the Start menu), but it's possible to create a form that's smaller than the desktop area. If you create a form that is smaller than the physical screen, the form should be centered vertically and horizontally on the screen, taking into account the Start menu, the main menu, and, if visible, the soft input panel (SIP). (See the section "Working with the Soft Input Control" later in this chapter.)
Creating Custom Dialog BoxesCustom dialog boxes are dialog boxes that you create yourself, using forms, for your application. The ShowDialog method is used to display your dialog box form. This method disables the parent form while the dialog box is shown. The dialog box returns a result to the calling form, but the public members of the dialog box are also available to the parent form after the call to ShowDialog has returned. The following code shows an example of calling a full-screen dialog box and testing the returned value:
AddDVDForm addForm = new AddDVDForm(); If you need to, you can use the FormBorderStyle and Size properties of the Form class to size a dialog box so that it's smaller than the screen size of the device. If you size a dialog box like that, you should also use the Location property to place your dialog box in the most convenient position on the screen. One possible use for a dialog box form that is smaller than the screen size is to present a Logon dialog box on top of the main form the first time the application is launched. A common task for an application that uses sensitive data is to require the user to log on before the data is accessed. It's important to make sure that an application that contains sensitive data is secure. For more information about securing your application, see Chapter 12. The problem with having a logon screen, rather than a logon dialog box, appear first in your application is that the logon screen will function as the main form of the application. This might not seem like a problem, until you close the form to free resources. Because the form is your application's main form, closing it will close your application. The solution is to have your main form call a logon form as a dialog box and continue or exit depending on the result of the dialog box. The DVD Catalog example application uses a logon dialog box to protect the user's DVD data. The application has a form called MainForm, as shown in Figure 4-1, which lists the DVDs in the user's collection. Figure 4-1 DVD Catalog application: MainForm. The application uses another form, called LogonForm, to request the user's logon details. Figure 4-2 shows what LogonForm looks like. Figure 4-2 DVD Catalog application: LogonForm. The following code is the Load event handler for MainForm. In this event handler, we need to create a new instance of the LogonForm object and call it as a dialog box. The logon form will return DialogResult.Ok or DialogResult.Cancel, depending on whether the user entered a valid user name or simply closed the logon form. If the user's details are valid, the main form will continue with its normal processing. If the user closes the logon form without entering a valid user name the main form will close the application.
private void MainForm_Load(object sender, System.EventArgs e) The Click event handler for the Logon button of LogonForm, shown in the following example code, checks the user's logon credentials, using the CheckUser routine defined elsewhere in the application. The event handler returns a dialog box result of DialogResult.OK if the user enters a valid user name.
private void LogonButton_Click(object sender, System.EventArgs e) If the user closes the form without entering a valid user name, the logon form's CancelButton_Click event handler returns DialogResult.Cancel to the main form, which will then close the application.
private void CancelButton_Click(object sender, System.EventArgs e)
Using Built-In Dialog BoxesThe built-in dialog boxes are encapsulated in the OpenFileDialog and SaveFileDialog classes. These dialog boxes can be used for opening and saving files in the device's file system.Both of these classes have a Filter property, which allows you to specify which file types will be displayed in the file list of the dialog box. Like custom dialog boxes, built-in dialog boxes return a DialogResult value to specify whether the results of the dialog box were successful. The following code sample shows the use of the OpenFileDialog class, and Figure 4-3 shows the code running in a Pocket PC environment:
OpenFileDialog openDialog = new OpenFileDialog(); Figure 4-3 The OpenFileDialog class in action on a Pocket PC device. The following code sample shows the use of the SaveFileDialog class, and Figure 4-4 shows the code running in a Pocket PC environment:
SaveFileDialog saveDialog = new SaveFileDialog(); Figure 4-4 The SaveFileDialog class in action on a Pocket PC device.
Working with the InputPanel ControlThe InputPanel control allows the user of a Pocket PC to enter textual information by using either an on-screen keyboard or a handwriting recognition panel. The InputPanel control appears at the bottom of a form whenever the form contains a MainMenu control or a ToolBar control.When the InputPanel control is available for use by the user, it is important to design the form so that the InputPanel control obscures no important controls when it is raised. This is especially true for controls that require text input. The two techniques to use in designing your forms are to have all the text-input controls above the top of the raised InputPanel control and to move controls on the form to make room for the InputPanel control. Remember to include scroll bars on the form if you opt for the second technique. This will allow the user to keep the InputPanel control raised and still have complete access to all the controls on your form. The code below demonstrates how to show the InputPanel control when a TextBox control receives the focus and hide the InputPanel control when the TextBox control loses the focus:
private void textBox1_GotFocus(object sender, System.EventArgs e) As has already been stated, it is important to be mindful of the use of the InputPanel control by the user when designing your forms. Remember to place any text-input controls above where the InputPanel control will be displayed or to move controls up when the InputPanel control is displayed. The EnabledChanged event is triggered when the InputPanel control is raised or lowered by the user or programmatically. Text-input controls that will be obscured when the InputPanel control is raised should be placed inside a Panel control. When the InputPanel is raised, you can reposition the Panel control at the top of the screen. The following code shows the EnabledChanged event handler moving a Panel control above the InputPanel control when the InputPanel control is raised, and moving it to the back to its original position when the InputPanel control is lowered.
private void inputPanel1_EnabledChanged(object sender, System.EventArgs e) Figure 4-4 in the previous section shows the InputPanel control with the on-screen keyboard selected.
Using the MainMenu ControlThe MainMenu control is added to the first form in a Pocket PC Windows application by default, but you will have to add it manually to any additional forms. Windows CE supports the MainMenu control but does not add it to any forms automatically. As mentioned, in a Pocket PC application, if you want the user to be able to choose to use the SIP or to choose which SIP to use, you will need to add a MainMenu or ToolBar control to the form.To add menu items to the MainMenu control, click the menu bar and type in the menu items your application requires. Figure 4-5 shows the MainMenu control in Windows Forms Designer. Figure 4-5 MainMenu control in Windows Forms Designer. Figure 4-6 shows the menu expanded showing the New, Open, and Save commands that have been added to the MainMenu control of the DVD Catalog sample application. Figure 4-6 The MainMenu control as it appears in a Pocket PC application. You can create a cascading menu structure with the MainMenu control, but a cascading menu should be used on a Pocket PC application only when it will not clutter the screen. A Windows CE application can be less conservative in the use of its menus because a Windows CE device generally has a larger screen and a more Windows-like appearance. The MainMenu control of a Pocket PC application should include functions that are necessary for the use of the application but not functions that will be used frequently by the user. You should place frequently used functions on a toolbar to allow the user easier access to them. Functions should not be duplicated between the main menu and a toolbar. This is different from the recommendation for desktop applications, where you should provide the user with several different approaches to accessing any of the application's functions. With a Pocket PC application, you need to be aware of the limited space available to your application and place access to the application's functions in the most appropriate location. Do not hide a function in a menu when the function is likely to be used every time your application is run.
Using the ToolBar ControlThe ToolBar control is a useful way of adding frequently used commands to a form. The ToolBar control is available for use in both a Windows CE project and a Pocket PC project. In a Pocket PC application, the toolbar is displayed at the bottom of the form. In a Windows CE application, the toolbar is displayed at the top of the form.As is the case with the MainMenu control, when a toolbar is added to a form, the SIP control is available to the user, so you should take care to design your forms with the SIP in mind. The toolbar acts as a container for buttons that the user can click to perform functions in your application. Each button can have a different image assigned to it from an ImageList control to help identify the button's function. The default image size is 16 by 16 pixels, but the image size can be changed to suit the images you want to use. Image size guidelines are provided in the section "General Design Guidelines" later in this chapter. The style of each button can be set to DropDownButton, PushButton, ToggleButton, or Separator. The DropDownButton style causes the button to display a pop-up menu when clicked. The PushButton and ToggleButton styles cause the buttons to look like standard buttons, but the ToggleButton style causes the button to stay down when clicked. The Separator style displays a space or a line between buttons, allowing clearer definition between button groups. When you have added a ToolBar control to your form, you add buttons to the ToolBar control using the ToolBar Button Collection Editor. With the ToolBar Button Collection Editor, you can define the type of buttons that appear on your ToolBar control by setting ToolBar button properties such as Style, DropDownMenu, and ImageIndex. The ImageIndex property accepts an index into the list of images in the ImageList control associated with the ToolBar control. Figure 4-7 shows the ToolBar Button Collection Editor for the ToolBar control in the DVD Catalog sample application. Figure 4-7 ToolBar Button Collection Editor. The following code shows an example of adding a ToolBar control to a form programmatically:
// Create ImageList object for use by the toolbar The preceding code first creates an ImageList object and then loads three bitmaps using the GetManifestResourceStream function to retrieve the images from the embedded resources of the application. The toolbar will use these bitmap images to display the three buttons that will be added to the ToolBar control. Then the code sets a reference to the ImageList object in the ToolBar control. Three ToolBarButton objects are created, made to reference an image in the ImageList object, and then added to the ToolBar control. The ToolBar control is then added to the current form. Finally an event-handling routine is associated with the ButtonClick event of the ToolBar control. This allows you to detect when the user taps a button in the toolbar and to take whatever action is required for the tapped button. An example of an event handler for the toolbar's ButtonClick event, from the DVD Catalog example application, is shown here:
protected void DVDToolbar_ButtonClick(object sender, This code example displays a message specifying which button was clicked. The button that was clicked is identified by inspecting the ToolBarButtonClickEventArgs parameter, which includes a reference to the button that was clicked. The IndexOf method of the Buttons collection in the toolbar returns the zero-based index of the button, which is numbered from the left side of the toolbar. Note that if you have used separator buttons in the toolbar, the number of functioning buttons will not be consecutive. Figure 4-8 shows how the toolbar should look. It shows the three buttonsAdd, Edit, and Deletein the finished application. Figure 4-8 DVD Catalog toolbar example.
Programming Form Activation and Deactivation on Pocket PCThe Pocket PC user interface guidelines have been created to ensure that applications running on these devices give good ergonomics and behave in a consistent manner. There are two significant recommendations relating to applications that differ from a desktop Windows PC. The first is that there should be only a single occurrence of an application running at any time. When you start an application from the Start menu, if the application is already running, that copy is reactivated. If it's not already running, a new copy is started. The .NET Compact Framework runtime automatically ensures that there is only a single occurrence of your application; there is no need to write any code to look for another occurrence of your application.The second significant recommendation for an application on a Pocket PC is that once started the user should not be able to close it. When a user switches to another application, the window for the new application fills the screen and hides your application in the background; it is deactivated. When the user selects your application again from the Start menu or by clicking the application's icon on the Most Recently Used (MRU) bar on the Today page, your application is activated once more.
Programming Activate and DeactivateWhen an application is deactivated on a Pocket PC device, the application should release as many resources as possible to conserve the limited resources of the device. It might be required to run in the background for a very long time, perhaps as long as days, until the user reactivates the application or resets the device, so you should try to design your application to use a minimum of resources while it is deactivated.When an application is deactivated, the .NET Compact Framework automatically performs a garbage-collection process to release memory resources that the application no longer needs. Garbage collection in the .NET Compact Framework has been optimized for the lower memory specification of the device rather than for speed and scalability, as in the full .NET Framework. All memory allocations are taken from a single pool so that it's easy to free up memory resources if the device starts to run low on memory. You will still need to specifically release resources such as open database connections, large objects in memory (such as datasets), and connections to COM ports. Two Form events are provided by the .NET Compact Framework to enable you to detect when your application is moved to the background or restored to the foreground of the system display windows. The Form.Deactivate event is used to detect when your application is minimized, and the Form.Activate event is used to detect when your application is brought back to the foreground of the system. The following code example shows event handlers in C# for both of these events:
private void Form1_Activate(object sender, System.EventArgs e)
Programming Form CloseIf your application conforms to Pocket PC user interface guidelines, you must not allow users to close the main form of your application. You must not put a Close option on the menu, and you must ensure that the form toolbar displays only the X icon (equivalent to Form Minimize on Windows CE .NET and desktop PC windows) and not the OK icon (which is the Form Close button).In a Pocket PC form, set the MinimizeBox property to true to display the minimize button (the X icon) or set the property to false to display a close button (the OK icon). The main form of your application should not be closeable. All dialog box forms that your application displays should be full screen and should be closeable through the OK icon to return to your main application form.
Closing of Applications by the Pocket PC ShellWhen the system becomes low on memory, Pocket PC developers using eMbedded Visual C++ have to respond to a WM_HIBERNATE message sent to the main window of an application by releasing memory and other resources. Developers using the .NET Compact Framework don't have to worry about this. There is no event an application receives to indicate that the operating system has requested the application to hibernate. Instead, the .NET Compact Framework runtime responds to this condition by garbage collecting and releasing cached JITted code.If resources on the device become low, the operating system will start to close applications that are running in the background. Because your application might be closed by the operating system while it is minimized, it is important that the application write any changes to data immediately or in response to the Deactivate event. If the application doesn't write data changes immediately or during the Deactivate event, there is a risk of leaving the data in an inconsistent state.
Handling the Tap-and-Hold EventBecause a Pocket PC device does not have a mouse, users cannot right-click a control. Instead, they must tap the control with the stylus and then hold the stylus in place until the context-sensitive menu is displayed. To provide context-sensitive menus for your controls, you use the ContextMenu control. The ContextMenu control is described in Chapter 3.If you want to provide functionality other than a context-sensitive menu to the tap-and-hold action on a control, you must trap the action manually. You should create a timer control on your form and set its interval to the amount of time you want the user to hold the stylus for before triggering your function. Capture the MouseDown event to start the timer and the MouseUp event to stop the timer. Capture the timer's Tick event to execute the code for the tap-and-hold action. You should also capture the MouseMove event if you want to allow the user to move the control without triggering the tap-and-hold action. The following code shows the technique just described to provide a custom tap-and-hold event for Form1:
private void timer1_Tick(object sender, System.EventArgs e)
Handling Pocket PC Hardware KeysA Pocket PC does not have a keyboard and relies on the use of a stylus and the SIP for most of the input from the user. A Pocket PC device does have some hardware keys available to it. Figure 4-9 shows a typical example of the hardware keys on a Pocket PC device.Figure 4-9 Pocket PC device hardware keys. It is possible to capture these keys in the KeyDown event that occurs when the user presses these keys. The Compaq iPAQ has a central pad that generates the following five different types of key codes:
The following code example shows a KeyDown event handler. The code uses the KeyCode of KeyEventArgs to detect which key has been pressed.
private void Form1_KeyDown(object sender,
Giving an Application Its Final TouchesOnce you've finished coding your application's functionality, you'll want to give your application an icon and provide a shortcut to the application in the Start menu of the Windows CE or Pocket PC device.
Associating an Icon with Your ApplicationTo associate an icon with your application, open the project Property Pages dialog box, select the General section, and enter the path to the icon in the Application Icon property. Figure 4-10 shows the project Property Pages dialog box.Figure 4-10 Project Property Pages dialog box.
Adding a Shortcut to the Start MenuAdding a shortcut to the Start menu will allow the user to launch your application more easily. To add a shortcut to the Start menu, place the shortcut in the \Windows\Start Menu folder on the device.The configuration file used to build your application's CAB file is used to define the shortcut that will be created for your application when it's installed on the device. If you use Visual Studio .NET to create your application's CAB file, a shortcut section will be included in the configuration file. The following section describes which sections of the configuration file need to be changed to create a shortcut for your application if you build the configuration file manually. Three sections of the configuration file are affected. The first section that you need to change is the DefaultInstall section. You use the CEShortcuts keyword to point to the section that will create the shortcuts for your application. The following code is an example of the DefaultInstall section from the configuration file of the DVD Catalog application:
[DefaultInstall] After pointing to the section that will define your shortcuts, you add that section into the configuration file. The format of the entries in this section are shortcut_filename, shortcut_type_flag, and target_file.
The following listing shows the Shortcuts section of the configuration file of the DVD Catalog application:
[Shortcuts] The third and final section that you will change is the DestinationDirs section. This section defines the paths to use for various other sections. You enter the shortcut's section name followed by the path to your shortcuts. The following listing below is taken from the configuration file for the DVD Catalog application:
[DestinationDirs] This topic will be covered in more detail in Chapter 6.
General Design GuidelinesThe "Designed for Windows for Pocket PC" logo program has some detailed requirements for applications written for the Pocket PC. The logo program specifies the usage of such things as icons, menus, toolbars, and the input panel. A handbook is available that details the design requirements for meeting the "Designed for Windows for Pocket PC" logo program criteria. The handbook can be downloaded from the Web site http://www.qualitylogic.com/certprograms/pocketpc_spec.html.On a Pocket PC device, there is no keyboard, so all text input needs to be done using the SIP. If you compare the use of the SIP and a keyboard, you will find that the SIP is time-consuming and error-prone. When you design your input forms, reduce the need to enter textual information by providing drop-down lists of the most common entries for each input. For example, the Task Input Form on a Pocket PC device uses drop-down list boxes to provide the user with the most common subjects for the task. Figure 4-11 shows the Task Input Form with the Subject drop-down list box displayed. Figure 4-11 Task Input Form showing the Subject drop-down list box. Remember that the user is using a stylus instead of a mouse to select items on your form. To aid the user in selecting items, make controls sufficiently large to avoid target misses. The recommended size for a button on a Pocket PC device is 5 millimeters (21 by 21 pixels) for a stylus target and 9 millimeters (38 by 38 pixels) for a finger target. Also provide sufficient space between controls to reduce the risk of a missed hit. This is particularly important if the commands perform cut or copy functions. As a general rule, you should consider the way the user is going to use your application. Minimize the distance between common controls and tasks so that the user is not constantly moving the stylus back and forth across the screen. Consider the way the device is held. The most frequently used or most important information should be positioned so that it's not obscured by the user's hands when he or she is entering data or selecting items. Group related controls together for ease of access. You should reduce the movement the user needs to make to perform the most common functions of your application. On a Pocket PC device, the screen's height is greater than its width. This is different from the standard desktop screen, which has a width greater than its height. You must be aware of this narrower display when you design your application's forms. Controls should be arranged vertically rather than horizontally to avoid making the user scroll the display horizontally to see all the controls. Forms should be designed to fit all the required controls onto one form without scrolling. This allows the user to see all the information that he or she requires without having to scroll the display. If a form can't be designed to display all the required controls without scrolling, the most important controls should be displayed first and secondary controls should be displayed in the area of the form that will need to be scrolled into view. Avoid overlapping forms and controls, especially in a Pocket PC application. Feedback to the user should be provided for the actions he or she performs. This feedback can be in the form of a sound or a change in the appearance of the form or controls. The use of graphics to enhance your applications is covered in Chapter 21.
SummaryIn this chapter, we covered properties of the Form class, using custom and built-in dialog boxes. We showed how to use InputPanel, MainMenu, and Toolbar controls. We covered how to detect when your application was activated and deactivated, and we explained what happens when your application is deactivated on a Pocket PC and how your application should respond to deactivation. We also looked at adding the finishing touches to your application, such as a shortcut in the Start menu and associating an icon with your application. Finally we covered some general guidelines for creating a user interface for your applications.
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||