Sample Controls in Windows
Sample Controls on Pocket PC
Sample Wizard in Windows
Sample Wizard on Pocket PC
Bienz.UI is a collection of several controls that make the development of user interfaces easier for the programmer. Currently, there are only three controls in the library, but this number will continue to grow. Most importantly, I tackled cross-device support from the get-go. This required me to learn a little bit more about how Visual Studio handles project files, but in the end I have an extremely maintainable library that compiles for multiple platforms.
This article talks about some of the struggles I had to overcome, and some of the limitations of the Smart Device Extensions for Pocket PC and the Compact Framework. Both the Smart Device Extensions (or SDE) and the Compact Framework (CF) are available in Beta from Microsoft right now. You can apply to receive the beta at the following URL:
Keep in mind that this beta is available by nomination only (which means that Microsoft can be selective about who may download it).
The Smart Device Extensions / Compact Framework Beta MUST be installed for you to work with any of the Pocket PC source code or example programs. It is NOT required for you to interact with the Windows portion of
Differences in the Framework
The Compact Framework is exactly as it sounds, it is a subset of the full .Net framework. Even so, I didn't find that any objects I needed were missing (keep in mind this is a fairly simple project). What I did find, however, was that a few objects had been renamed, some methods had different parameters, and some objects behaved slightly different. To me, this is not very acceptable - I doubt it will be to Microsoft in the final product either (we can only hope).
Below, I have compiled a list of the main differences I found between the full framework and the Compact Framework. I'm sure there are many other differences, these ones were the ones that effected this project:
- Control designer not included
I was very happy to see that the form designer made it in this beta as promised, but the control designer was still left out. I was a bit confused about this, since they are so similar. In fact, when I need to work on a Pocket PC control, I simply change the base class to
Form and then I can use the form designer. I've even used conditional-compile statements to do this for me and setup two project profiles so I can 'toggle' this on and off.
- Cannot design inherited forms
Even though the form designer works in this beta, you still cannot design forms that inherit from another form. (And therefore, you cannot design controls that inherit from other controls - even if you use the conditional-compile trick mentioned above).
- Cannot set the name on controls
In fact, there doesn't appear to be a name property at all...?
- Cannot set tab index or tab stop on controls
There is obviously no tab key on the Pocket PC, but the order the controls are addressed (drawn, z-order, etc.) appears to be the order in which they are defined in your .CS file.
- Image properties cannot be set using the designer
Even if a control has an
Image property, it cannot be set in the form designer in this beta. Microsoft shows a work-around where the image is added to the assembly as a resource and then loaded by name. I use this work-around frequently in the Pocket PC version of
Bienz.UI, but it is very time-consuming.
- AddRange is not supported in the control arrayThe windows form designer defines controls and then adds all of them to the Controls collection in one step using
Controls.AddRange. Since the
AddRange method is not supported on Pocket PC, each control must be added in its own step by calling
- Owner parameter for dialogs and message boxes left out
I'm not sure why this is; maybe all dialogs in Pocket PC are at the system level and don't have owners?
- MessageBox implementation differs
Message box icons are still similar (if not identical) in appearance, but have different names.
MessageBoxIcon.Information on the Windows side is
MessageBoxIcon.Asterisk on the Pocket PC. The Pocket PC version also has a required third parameter that specifies which button will be the default button (the one that will be clicked when the user presses the action button on the Pocket PC). This parameter is an enumeration, but the enumeration is simply Button1, Button2 and Button3.
- CheckChanged Event missing from Checkbox controlYou can still use the click event.
- Control.Font causes exceptionThe
Font property of the
Control base class is there, but attempting to read or write it causes an exception to be thrown. This was a major pain for me because I had to make my own
Font property using the
new modifier, but if I need to cast my derived control as a
Control, I won't be able to access this property. If you find a work-around, please let me know.
Bienz.UI Included Controls
DriveCombo ( Windows Only )
The drive drop-down list shows all drives currently available in the machine including local drives, removable drives, and network drives. This control inherits from the standard drop-down list and uses my
Bienz.SysInfo class to obtain the system information required to render the control. You can read about
Bienz.SysInfo in this article.
The list displays the label of the drive, if it is available, or a description of the drive type if not. An icon is also drawn for the drive using the icon supplied by
Bienz.SysInfo (which in turn comes from the shell). Other articles have discussed obtaining this icon and using it in a similar fashion, but users have noticed the black border that appears around the icon in Windows XP. I was able to get around this ugly black border by using the 32x32 icon supplied by the shell and re-sampling it down to 16x16. This requires a bit more overhead, but since the list can never contain more then 26 items, I felt it was worth the trade off. Besides, it gives the icons a nice fuzzy high-color appearance.
SelectedItem property of this control returns an instance of the
VolumeInformation class built into
Bienz.SysInfo. This class provides detailed information about the selected drive. Again, read this article for more information.
ImageButton ( Windows & Pocket PC )
ImageButton was built for two reasons. First and foremost because Pocket PC does not support the image properties of its full-framework button counterpart. Second, I wanted to be able to make Flash-like buttons that supported Mouse-Over images, etc. The button supports images and events for the following states:
- Mouse Over (Windows Only)
ImageButton also supports the drawing of text in any font/size over the center of the button. You can also define the number of pixels to offset the text when the button is pressed. The text can be offset in both the X and Y directions and can also be offset by a negative amount.
Wizard ( Windows & Pocket PC )
The Wizard component is by far the coolest addition to
Bienz.UI. It really needs its own documentation and hopefully I will have the time to write it soon. The Wizard component provides a framework for creating highly customizable wizard steps in your own application. This is achieved using three main classes:
Wizard is a form class. The form is the same dimensions as most standard wizards you will find in Windows. It includes both header and sub header labels whose text can be changed, a stock image which can also be changed, and back, next, cancel, and help buttons that can be shown, hidden, enabled and disabled.
In Windows, the buttons appear as normal buttons with text depicting the action that will be performed when clicked. On the Pocket PC, however, I wanted to preserve as much space as possible for the pages. I decided to move the buttons down to the 'task bar' area, and use image buttons in place of the standard text buttons. If anyone finds this to be a problem, or if you feel you have a better solution, please let me know.
WizPage is a base control that you derive from to design your own custom page or step. In both Windows and Pocket PC, the
WizPage base control is the correct dimensions to fit inside the corresponding
Wizard. This base control also provides built-in properties that will prove useful to you. The
Wizard property, for example, returns to you the
Wizard instance on which your page is being displayed.
WizPageCollection is not used on its own, rather it is used as a property of the
WizPageCollection contains all of the pages that have been added to the
Wizard, and also includes searching capabilities.
Since you may wish to add and remove pages from the
Wizard on-the-flay based on user input,
WizPages may not always be at a fixed index.
WizPageCollection allows you to search the collection for pages based on type using methods such as
FindLast(Type), and also by relative position using methods like
WizPageCollection also notifies the
Wizard of changes automatically, which in turn allows the
Wizard to enable or disable buttons and change the 'Next' button to say 'Finish' as appropriate.
One of the problems I faced was getting the two different projects to share the same source files. This was obviously important, since I didn't want to have to maintain changes in two separate .CS files. However, whenever you chose Add Existing Item for a file in another directory, it is copied into your projects directory. The answer to this problem was to put both projects in the same folder and give them different names.
The obvious short-coming to this approach, is that the compiler outputs files for both projects into the same folders (bin\Debug and bin\Release). I realized this and changed the project settings to output files into their own folders (bin\PocketPC\Debug, bin\Windows\Debug, etc).
Next, though, I worried about the compilers stepping all over each other in the obj folder. Intermediate files go in the obj folder whenever a build is performed. I was concerned that the build would always place files in obj\Debug for example, and then later move them to bin\PocketPC\Debug. It turns out that the compiler is a bit smarter then that (thankfully), and it actually puts intermediate files in obj\PocketPC\Debug automatically.
Lastly, I needed to address the differences between the full framework and the Compact Framework. This was easily solved using conditional-compile statements. The only thing to watch out for here, is using conditional statements in automatically generated code blocks. This caused me problems a few times before I got in the habit of doing it right. For example, you will almost certainly need to use conditional statements in your
InitializeComponent method. But that code is automatically generated by the form designer, which means your conditional statements will be wiped out the next time you open the designer. The trick is to duplicate the entire method and put conditional statements around the whole thing. At least the designer does seem to find the right version of the method when you do it this way, and your changes won't be lost.
I learned a little bit more about both Visual Studio .NET and the Compact Framework then I really wanted to know to when developing this multi-device library. Even so, it went much more smoothly then anticipated, and obviously much more smoothly then any multi-device integration on any other platform.
Microsoft has already taken great strides in making this the future of device application development, and even in the beta I give them full kudos. I anxiously await the final release, but even months away, I wouldn't shy anyone away from getting started writing their own .Net Pocket PC Applications.