In-Depth

Spice Up Your Windows Forms

Users expect to find popup-style windows, irregularly shaped forms, and collapsible and dockable controls in a robust application. Learn how to implement the three features that can make or break your next Windows Forms app's UI.

Technology Toolbox: VB.NET, C#, .NET Framework

Today's users are more demanding—they expect to find Microsoft Office application features, such as popup-style windows, irregularly shaped forms, and collapsible and dockable controls, in a robust application. In this article, we'll show you the basics of how to implement three features that can make or break the UI of your next Windows Forms application.

Windows Forms typically follow a set design that is rarely compromised; that is, they are square. Creating irregularly shaped forms under a non-.NET environment is difficult to say the least. Fortunately, the .NET Framework provides a simple and easy-to-use API that improves your forms' functionality and spices them up.

As with any good visual element, misusing irregularly shaped forms can detract from the professionalism of the end product. Two reasons for using an irregularly shaped form come to mind. The first is functionality. Irregularly shaped forms are a good choice if they highlight key controls, improve the end user's experience, and achieve greater functionality. For instance, Windows Media Player is a prime example of an irregularly shaped form that's defined by functionality. The internal presentation of data is essentially in a box; however, key controls, such as the media components, are highlighted and appear outside the box.

The second reason has to do with presentation. Design can be as simple as providing the rounded corners to a Windows Form, à la MSN Messenger, or creating a splash screen that demonstrates a company's technological prowess. When presentation is the determining factor for employing an irregularly shaped form, exercise good taste and, if possible, consult a design team.

Develop an Irregularly Shaped Form
The first step to designing an irregularly shaped form is determining which of the two uses—functionality or presentation—you'll employ. Be sure to use a high-quality image as the background for the form. Neglecting to do so might hinder Windows' capability to paint the shape later. For example, let's say you're using an irregularly shaped form for presentation and are modeling the application after the look and feel of MSN Messenger 6.2.

Cut out the rounded shape of the form you want to use in the application, then choose a background color for the image. Choose this color wisely. It will be used as the TransparencyKey property for the form that this image will live on. This means that every area of the form where the background color is the same as the color of the image background will be transparent as well. That is why choosing an oddball color such as lime or hot pink is a smart idea. You can do this in Microsoft Paint (see Figure 1).

Once you create your image with the appropriate background color, you need to set the BackgroundImage property of your form to your newly created image. Next, change the FormBorderStyle property from the default Sizable value to None. Setting this property removes the border from the application; the image you just added as the form's background now dictates how the form border should appear. Finally, set the TransparencyKey property of the form to the same color as the image background; in the example, it's Lime #00FF00 (see the sidebar, "Change Your Color Depth," for more information on how to get your form to display properly).

A curved, bordered Windows Form is displayed after you run the application (see Figure 2). However, aside from pressing Alt-F4, you can't close the form, let alone move it. The next step is to add events to control closing and moving the form.

Closing the form is easy. Simply add a button, then add this code in the Click event:

this.Close();

Allowing the form to move is a bit more complex, but it's essential for an irregularly shaped form. Add three events—MouseDown, MouseMove, and MouseUp—that will handle the mouse, which, in turn, will handle dragging the form (see Listing 1).

Now you need to get your form to move smoothly across the screen and not jump when the mouse begins a drag event. Use the offsetX and offsetY variables to track where the user clicks on the form with the mouse. When the drag begins, you set the location of the form to the location of the mouse, minus the original offsetX and offsetY values. Simply keep track of when the mouse is clicked up or down to know when you should and shouldn't be dragging. The form will move even when the user clicks up if you leave out this code in the MouseUp event:

if (e.Button == MouseButtons.Left)

Add Extra Features to Your Form
Now that you've added the basic features, you might want to give your irregularly shaped Windows Form additional functionality with a little extra code. You might consider resizing the form; redisplaying the menu through a mouse move, à la Windows Media Player; or even using a Click event to display a main menu, similar to MSN Messenger.

As an example, add a menu to your form and then add a few main menu items. Next, change the background of the background image to a color that works both transparently and when it's displayed. In our case, we changed the background color from a lime green to a more suitable gray. Make sure to set each menu item's visibility to false in the form load event.

The next step yields the bulk of the work for the button Click event to display the menu and change the background to visible. You must take other factors, such as resizing the form, into account, because adding the menu changes the background size of the form. Furthermore, the amount of space between your menu and the form is directly related to the amount of border you have on your ISF background image, as this code demonstrates:

if(this.FormBorderStyle == 
   FormBorderStyle.None)

{   
   this.FormBorderStyle 
      = FormBorderStyle.Fixed3D;
   this.TransparencyKey = 
      Color.SomeDifferentColor;

   this.Height = 425;  

   // Changing the Height and Width to 
   // allow for the newly sized form

   this.Width = 467;
   menuItem1.Visible = true;
}

Finally, after you add the capability to display the menu, add the inverse of this code to hide the menu. This effectively adds an MSN Messenger-style tool to your arsenal to spice up your Windows Forms.

The second way you can spice up your Windows Forms is by using notifications. Older VB code notified users by calling a FlashWindow method; today, you can easily create stylish user notifications by using alpha blending and transparency. Two types of user notifications are popular or unpopular, depending on your take: the MSN Messenger-style popup and the Outlook-style fade window (see Figure 3).

Generally speaking, getting important or time-critical data to the user in an efficient manner is important. For instance, instant messaging and system-monitor notifications require immediate and effective communication to the user. After determining the need for notifications, you need to determine if the notification is important enough to stop a user's current task completely and change his or her focus to the incoming data. A good user interface should not be too intrusive. The user should be notified and be given the ability to continue to work despite the notification. Your design should focus on giving the user access to notification information without requiring prolonged periods of attention. Carefully choose the information that will be displayed to the user, then choose a size for the notification that's large enough to display this information but not large enough to overly distract the user.

Create Outlook-Style Notifications
Microsoft Outlook 2003 can alert users of new mail while enabling them to access the mail quickly or ignore the notification and continue working. To create this type of notification, use a Windows Form, size it accordingly, and implement some timer-based code that sets the opacity of the form. Opacity is a property setting from a scale of 0 to 1. You can simulate the fade-in and fade-out of an Outlook 2003 notification by setting the opacity to different percentages (see Listing 2).

Next, add some code for the MouseHover, MouseEnter, and MouseExit events. The idea is to pause the fade-out of the notification when a user hovers over the form. You can even add other controls to your notification form, such as a LinkButton that can open up a details form if you click on it.

Creating MSN Messenger-style notifications is a bit more complicated. They employ essentially the same concept as Outlook 2003-style notifications, but you must place the popup at the bottom of the screen. You can determine this location by taking the size of the working area of your desktop, then adding the size of the form you'll need to hide below the working area. Use this code to get the area of your screen, minus the Start menu:

Size desktopSize;
desktopSize = 
   SystemInformation.WorkingArea.Size;

Next, you need to calculate where to pop up the form. This calculation helps account for varying resolution sizes, rather than giving a fixed point as shown in the Outlook-style demonstration:

int height = desktopSize.Height +
   this.Size.Height;
int width = desktopSize.Width;
this.SetDesktopLocation(height,width);

Once you know where the form should start its ascent from, use this code to "lift" it out of your screen:

Size desktopSize;

desktopSize = 
   SystemInformation.WorkingArea.Size;

int height = desktopSize.Height;         

if(this.Top >= desktopSize.Height 
   - this.Size.Height)

this.Top -= 10;

You've now created a Messenger-style notification that will alert the user gracefully of information that might require his or her attention (see Listing 3). You can also plug right into the Messenger API and grab an alert or even use Microsoft's Alerts SDK. However, this requires a bit more work and essentially does the same thing: spices up the Windows Form.

Create Dockable Controls
The ability to move, resize, and dock controls on a form is a must-have feature for power users. That said, you don't want users to move buttons and labels around forms and resize them. Rather, users can move, dock, and resize a container control around a form. A container control can be a PictureBox; a Panel; or a GroupBox, which contains other controls. The beauty of container controls in Windows Forms (and forms themselves) is that they handle some of the complexities of docking automatically. Build a dockable panel in your Windows Forms by creating a control named DockingControl that inherits from Panel. DockingControl handles the complexities of moving and docking a panel.

Create a new Windows Control Library, add the Imports statement for the namespaces you'll need, and modify the class to inherit from Panel:

Imports System.Windows.Forms
Imports System.Drawing
Imports System.Drawing.Drawing2D

Public Class DockingControl

   Inherits System.Windows.Forms.Panel

Drag DockingControl around a form by using the same code you used to drag the irregularly shaped form, except that this time we've written the code in VB.NET rather than C#, so you'll see a slightly different syntax (see Listing 4).

Now you need to dock the control to the bounds of the form. Modify the MouseMove code to check constantly for the edges of the form. The panel docks into place automatically once it gets within a point of a stationary edge (this can be the edge of a form or another docked control):

If MyBase.Left < 1 Then
   MyBase.Dock = DockStyle.Left
   _dragging = False

ElseIf MyBase.Top < 1 Then
   MyBase.Dock = DockStyle.Top
   _dragging = False

ElseIf
   ' Remaining code omitted for
   ' brevity

End If

To undock the control, check that the panel is being dragged, then check to see if the control is docked already. The trick is to set the panel back to its previous size and move it far enough away from a stationary edge so it doesn't dock automatically to something else. You can add this simple code in the MouseMove event, along with the code to dock the control:

If MyBase.Dock <> DockStyle.None Then
   If MyBase.Dock = DockStyle.Left Then

      MyBase.Dock = DockStyle.None
      MyBase.Size = _size
      MyBase.Left = 5
      Return

You can easily create a flexible control that can handle docking, resizing, and dragging. This type of control, along with irregularly shaped forms and stylish notifications, will spice up your Windows Forms apps, giving your users the type of flexible, modern, consistent UIs they've come to expect.

About the Authors
Andrew Flick is a .NET technical evangelist for Infragistics Inc., a Microsoft Visual Studio Industry Partner. He is responsible for authoring reference applications and .NET technology articles, as well as delivering Infragistics' technology demonstrations worldwide. Andrew is a Microsoft .NET MVP and is the chair of the INETA Academic Student Committee. Reach Andrew at [email protected].

Jason Beres is a .NET technical evangelist for Infragistics Inc., a Microsoft Visual Studio Industry Partner. Jason is a Microsoft .NET MVP, is on the INETA Speakers Bureau, and is the cochair of the INETA Academic Committee. He is the author of Sams Teach Yourself Visual Studio .NET 2003 in 21 Days and the coauthor of Visual Basic .NET Bible and C# Bible (both from Wiley). Reach Jason at [email protected].

comments powered by Disqus

Featured

  • Compare New GitHub Copilot Free Plan for Visual Studio/VS Code to Paid Plans

    The free plan restricts the number of completions, chat requests and access to AI models, being suitable for occasional users and small projects.

  • Diving Deep into .NET MAUI

    Ever since someone figured out that fiddling bits results in source code, developers have sought one codebase for all types of apps on all platforms, with Microsoft's latest attempt to further that effort being .NET MAUI.

  • Copilot AI Boosts Abound in New VS Code v1.96

    Microsoft improved on its new "Copilot Edit" functionality in the latest release of Visual Studio Code, v1.96, its open-source based code editor that has become the most popular in the world according to many surveys.

  • AdaBoost Regression Using C#

    Dr. James McCaffrey from Microsoft Research presents a complete end-to-end demonstration of the AdaBoost.R2 algorithm for regression problems (where the goal is to predict a single numeric value). The implementation follows the original source research paper closely, so you can use it as a guide for customization for specific scenarios.

  • Versioning and Documenting ASP.NET Core Services

    Building an API with ASP.NET Core is only half the job. If your API is going to live more than one release cycle, you're going to need to version it. If you have other people building clients for it, you're going to need to document it.

Subscribe on YouTube