As a long time Windows programmer dating back to the days of Microsoft C and the Windows SDK, I recently found myself digging into the latest Microsoft development tool for creating Windows applications. Namely .NET Windows Forms.
Though I had abandoned the old C compiler some time ago for Visual C++ and the Microsoft Foundation Classes (MFC), I sensed that .NET Windows Forms would again require this old dog to learn some new tricks.
What follows is my attempt to pass on some lessons learned for .NET Windows Forms programming from the Visual C++/MFC developer’s perspective.
What constitutes a trick?
I consider anything as we, Visual C++/MFC developers, use on a regular basis to write Windows applications that does not work exactly the same way in .NET Windows Forms to be a new trick that we have to learn. This can be anything from common coding techniques to new or different IDE behaviors like the notable absence of ClassWizard in Visual Studio .NET (VS.NET).
Before We Get Started
For the record, I am aware that many of the tried and true MFC techniques still work in VS.NET as MFC is still supported. However, I have decided to go whole hog into .NET and write managed applications with the
System.Windows.Forms namespace and the new C# programming language. For those of you who have made the same choice, I hope these tricks will save you some time and possibly some frustration while making your transition from MFC to .NET Windows Forms programming.
Trick #1 - Getting Used to a New Name
Though not much of a programming trick, the first thing I found I had to get used to was the term "Windows Forms". To me, there is a slightly negative connotation to the term "Forms". Previously as a "Windows Programmer" or “Windows Developer”, I could justify my work as challenging, encompassing the vast technologies surrounding Microsoft’s Windows platform. Now, as a "Windows Forms Programmer", it is difficult to differentiate myself from Aunt Ethel. After all, even Aunt Ethel could program a simple "form", right?
Clearly there was a significant VB influence in naming the new way to develop traditional Windows applications in .NET. Now, after years of being a distinguished C++/MFC developer and holding myself to a higher standard than run of the mill VB programmers, I'm forced to join them under the Windows Forms umbrella. At least the results of our programming efforts are now being referred to as "smart clients" rather than "fat clients". As the saying goes, you win some and you lose some.
Trick #2 - Walking a Straight Line
Some time ago, Microsoft adopted the use of horizontal lines rather than traditional group boxes to separate different areas of screens and dialog boxes. Take a look at Tools-Options dialog in MS Outlook for an example of this. The motivation for the shift from traditional group boxes to the newer line technique was probably one of aesthetics. Compare Figures 1 and 2. Overuse of group boxes (as seen in Figure 1) is definitely not as pleasing to the eye as the clean look achieved by using lines (as seen in Figure 2).
Like many Windows developers, especially corporate programmers, I took my lead directly from Microsoft and started using the line technique in my applications. In the Visual C++ 6.0 (VC6) resource editor, lines were pretty easily achieved by dragging the “
Picture” control from the Controls Palette and dropping it onto your dialog. Next, I would set the “
Color” property to “
Etched” and drag the sizing rectangle on the design surface so that the control was only a single pixel in height. Voila, you have a line that can easily be moved and sized appropriately in the dialog resource editor.
Imagine my surprise when designing my first dialog in .NET Windows Forms and discovering that the old Picture Control technique I’d come to love didn’t work any longer. First, there was no identically named control in the VS.NET toolbox. Second, when attempting the technique with the
Picture Box, the closest control in name to the control used in the VC6 environment, several things were amiss. There wasn’t a
Color property with
Etched as a choice and trying to drag its sizing rectangle down to a single pixel was not allowed within the VS.NET form designer.
My next instinct was to do a quick search of Google Groups (dejanews.com for my fellow old dogs). Not surprisingly, I quickly found other individuals wondering how to accomplish the same thing. Surprisingly, though, most respondents were pointing the questioner to various manual drawing techniques involving the use of GDI+ and the
System.Drawing namespace. As impressive and easy as GDI+ may be to use, I was not ready to give up on a technique that would allow me to accomplish line drawing directly in the VS.NET designer.
Finally, after some more sniffing around, I discovered that by dragging an ordinary
Label control onto the form clearing its “
Text” property, setting its “
BorderStyle” property to “
Fixed3D” and it’s “
Height” property to 2 pixels, I was able to achieve the same affect as I was used to in the VC6 resource editor. (Note: for vertical lines, set the “
Width” property to 2 rather than the “
Height” property.) Finally, I can walk a straight line with my new leash on.
Trick #3 - Choosing the Right Group
Nothing upsets me more than to run across a Windows application that incorporates standard radio buttons without properly supporting keyboard navigation. Namely, the arrow keys should rotate the selected/checked radio button among the group of mutually exclusive choices. Undoubtedly, if not implemented correctly, the arrow keys will march the selected/checked radio button down the list of mutually exclusive choices and then instead of returning to the first choice, move focus to the next control on the screen or dialog.
For example, pressing the down arrow key twice on the dialog shown in Figure 1, with improper radio button behavior, may result in selecting the “No Security” radio button followed by the “OK” button rather than the first radio button. Lack of proper keyboard behavior has caused me to continually preach that “the devil is in the details” to the pups I’ve run across in my career.
VC++/MFC didn’t do us any favors in terms of making this behavior automatic or even discoverable for that matter. Many developers simply put a group box around the radio buttons and expected everything to be fine. Not only did that contribute to an ugly looking interface (see Trick #2), it also failed to fix the problem. It turns out that to accomplish the correct behavior, a combination of “
Tab stop” and “
Group” property settings is needed. Specifically, the “
Group” and “
Tab stop” properties must be set on the first radio button in the group (“Pretend to be a secure operating system” in Figure 1) and on the first control after the last radio button in the tab order on the dialog (“OK” button in Figure 1). Also, make sure to uncheck the “
Tab stop” property for radio buttons other than the first one in the group.
For Windows forms, the first instinct of most programmers is in fact the way to accomplish the correct behavior. In Windows Forms, the “
Group Box” control is a container control, meaning that other controls can be added to it. As such, it provides the proper radio button behavior for radio buttons that are in the container. If you buy the argument that “Group Boxes” add visual noise, the “
Panel” control provides the same behavior without drawing the border and text that are found on a “
For instances where you need more than one group of radio buttons, you can use many panels together as shown in Figure 3 or even nest them as necessary. Notice the tab order indicators on the radio buttons and how they have a “dot” sub number (e.g. 2.1, 2.2) indicating their order within the panel that contains them.
As I said, time and time again I run across this mistake in Windows applications. Hopefully this trick will help you get it right whether you are writing a Windows Forms or a traditional C++/MFC application.
Wrapping it Up
To wrap things up, I thought I would put some subjective rankings to the old and new tricks. With these, we ought to be able to judge whether the new way to write traditional Windows applications is better or worse than the old way, right? Well maybe the rankings won't be scientific enough for that, but we'll have fun talking about it.
Table 1 shows how this month’s tricks rank including some commentary about the rankings. With these early results, I think it's too soon to determine which approach is better. Stay tuned, as I learn more new tricks, I will let you know.