Comments
Richard Davies wrote: The UK has a good crop of technology pioneers in cloud computing - for example ElasticHosts, FlexiScale, Flexiant, OnApp - and also some strong government initiatives such as G-Cloud. We will have to see whether this kind of technical leadership converts into swift mass-market adoption or not.
Cloud Expo on Google News

SYS-CON.TV
Cloud Expo & Virtualization 2009 East
PLATINUM SPONSORS:
IBM
Smarter Business Solutions Through Dynamic Infrastructure
IBM
Smarter Insights: How the CIO Becomes a Hero Again
Microsoft
Windows Azure
GOLD SPONSORS:
Appsense
Why VDI?
CA
Maximizing the Business Value of Virtualization in Enterprise and Cloud Computing Environments
ExactTarget
Messaging in the Cloud - Email, SMS and Voice
Freedom OSS
Stairway to the Cloud
Sun
Sun's Incubation Platform: Helping Startups Serve the Enterprise
POWER PANELS:
Cloud Computing & Enterprise IT: Cost & Operational Benefits
How and Why is a Flexible IT Infrastructure the Key To the Future?
Click For 2008 West
Event Webcasts
Customizing the PictureBox Control
Customizing the PictureBox Control

The Windows Forms namespace in .NET includes a number of classes for building Windows-based applications. One such class is the PictureBox control, which displays an image within a control window. This article shows how to extend the PictureBox control in a custom PhotoBox control that can preserve the aspect ratio of a displayed image, and discusses how to use this control in the Windows Forms Designer window of Visual Studio .NET.

Figure 1 shows a photograph in a standard PictureBox control with the SizeMode property of StretchImage. This setting stretches and distorts the image to exactly fit the bounds of the window. Figure 2 shows the same photograph using the PhotoBox control built in this article. As you can see, our new control will preserve the relationship of objects within the image, which is what we mean by preserving the aspect ratio.

It is a bit surprising that Microsoft failed to address this issue in the original PictureBox control. Fortunately, .NET controls are designed to permit extensions such as the one we present here, so a workaround is possible.

For the purposes of this article I will assume you have some understanding of C# and the use of class members such as properties and events. I also presume that you know how to create a Windows Forms application and define event handlers in Visual Studio .NET.

The PictureBox Control
Before we create our new control, a brief discussion of the PictureBox control is in order. This control inherits from the Windows Forms Control class, and provides the Image property to retrieve or assign the image to display, and the SizeMode property to retrieve or assign how the image should be displayed.

As an example, an application might define an Open menu that uses the OpenFileDialog class to accept an image from the user. Listing 1 shows a possible Click event handler for such a menu. This code creates a Bitmap object from a selected file and assigns it to the Image property of a PictureBox control. Of course, in production code, you would want to handle any exceptions that might occur while opening the file or loading the image.

You can create an application much like the one shown in Figure 1 by adding a PictureBox control to a form with its Dock property set to Fill and its SizeMode property set to StretchImage. Create a menu bar with an Open menu, and use the code from Listing 1 as a Click event handler for this menu.

Run the program and open a photographic image. As you resize the form, notice how the image is stretched and distorted to exactly fit the window. The remainder of this article shows you how to create a custom control similar to the one shown in Figure 2, which can scale an image within the window. We will call this the PhotoBox control.

Creating the PhotoBox Control
A custom control in .NET is created by deriving a new class from an existing control class. The Windows Forms namespace provides the Control class for basic control behavior, and the UserControl class is used for customized combinations of controls. For our purposes, we would like to extend the PictureBox class, so we define our new PhotoBox class as follows:

public class PhotoBox : System.Windows.Forms.PictureBox
{
// Definition of class
}

To define this class in Visual Studio .NET, create a new project called MyControlLibrary as a Windows Control Library. In this library Visual Studio will define a UserControl1 class, which you should delete. Then add a new User-Control class, called PhotoBox, to the library. Note that the new class automatically appears in the Toolbox window under the Windows Forms tab whenever a form is displayed. An existing library can also be added to the Toolbox window by right-clicking the window and selecting the Customize Toolbox... option.

Visual Studio .NET will derive your class from the UserControl class. Simply modify the base class in the PhotoBox.cs file to use the PictureBox class instead, as shown in the prior code excerpt.

Adding a New SizeMode Setting
Our implementation requires a new SizeMode setting, which we will call ScaleImage. The PictureBoxSizeMode enumeration defines the four possible settings supported by the PictureBox control, namely the Normal, StretchImage, AutoSize, and CenterImage members. To create a new setting, we will create a PhotoBoxSizeMode enumeration that provides an additional member. This enumeration is shown in Listing 2.

Note how the four members defined by the PictureBoxSizeMode enumeration are repeated in Listing 2, and how their values are assigned to the corresponding PictureBoxSizeMode values. This will permit us to use these values with either the PictureBox base class or the PhotoBox class interchangeably. Our new SizeMode setting is defined by the ScaleImage enumeration member.

Implementing the PhotoBox class
The new PhotoBox class inherits most of its behavior from the PictureBox class. We need to implement the behavior for our ScaleImage setting, but would also like to preserve the existing behavior for the common SizeMode settings. There are three important aspects of our implementation: a new SizeMode property, a new drawing behavior, and a new resize behavior. The complete listing of the PhotoBox class is shown in Listing 3. The following sections discuss these aspects of this listing.

The SizeMode Property
First, take a look at the SizeMode property. This uses an internal private _sizeMode member to hold the actual value represented by this property. We use the new keyword to indicate that our property replaces the existing SizeMode property in the base PictureBox class.

Also important here are the attributes defined in brackets prior to the property definition. These define how a visual designer such as Visual Studio .NET presents this property in the Properties window. A short list of some useful attributes defined by the System.ComponentModel namespace, including the ones used by our PhotoBox class, follows. You can see the complete list by displaying the classes derived from the Attribute class in the online documentation for the .NET Framework SDK.

  • BrowsableAttribute: Determines whether a property or event should appear in the Properties window
  • CategoryAttribute: Determines which category the property or event belongs to
  • DefaultEventAttribute: Defines the default event for a class. In Visual Studio .NET, a double-click on the control in the designer window adds a handler for the default event
  • DefaultPropertyAttribute: Defines the default property for a class
  • DefaultValueAttribute: Defines the default value of a property. Nondefault values are displayed in bold in the Properties window
  • DescriptionAttribute: Defines a short description of a property or event
  • ReadOnlyAttribute: Defines whether the property should be treated as read-only by Visual Studio .NET

    In C#, the "Attribute" section of these classes may be omitted when defining an attribute, which is how we use them in our code.

    The OnPaint() Method
    In Listing 3, we override the OnPaint() and OnResize() methods to add the proper behavior for our ScaleImage enumeration to the painting and resize logic, respectively. We'll examine the OnPaint() method first.

    The OnPaint() method begins by assigning a value to the base.SizeMode property and invoking the base.OnPaint() method. The base keyword accesses the base class, in this case the PictureBox class. These lines preserve the existing PictureBox paint behavior by drawing the image for all SizeMode property values other than the ScaleImage setting, and invoking any Paint event handlers registered with the class.

    In the case where the SizeMode property is set to the ScaleImage setting, the subsequent lines implement this setting by first clearing the drawing area, and then scaling the image to fit within the control. This uses a private ScaleToFit() method to calculate the rectangle within the control where the image should be drawn, and then the Graphics.DrawImage() method to draw the actual image on the screen. We will not discuss these methods in detail here. The ScaleToFit() method is a standard image calculation that you can examine at your leisure; the DrawImage() method is provided by the Graphics class for drawing image objects on a GDI+ drawing surface.

    Note that the logic for our ScaleImage setting has a slight performance problem. We set the base.SizeMode value to Normal to ensure that the PictureBox.OnPaint() method doesn't throw an exception. This has the side effect of drawing the image in Normal mode, after which our code redraws the image in ScaleImage mode. A more robust implementation might bypass the PictureBox control entirely and inherit from the Control class directly. We didn't do this here since we would then have to implement the BorderStyle property and all of the SizeMode settings, making for a rather long article. The point here is to show how custom controls can be created and integrated into the Properties window of Visual Studio .NET, which our PhotoBox implementation does quite well.

    The OnResize() method
    The OnResize() method in Listing 3 simply overrides the base method of the same name. This method ensures that the client area of the control is invalidated whenever the SizeMode property is set to ScaleImage. The base.OnResize() method is called to ensure the logic in the base class is executed and any Resize event handlers are called.

    Using the PhotoBox Control
    The PhotoBox control can be used in Visual Studio .NET just like any other Windows Forms control. Create a new Windows Application project and drag a PhotoBox control from the Toolbox window onto the form. Create the form shown in Figure 2 and use an Open menu with a Click event handler similar to the one shown in Listing 1. Run the application and watch how a displayed image changes as the application window is resized.

    Also examine the properties of the PhotoBox control in the Properties window of Visual Studio .NET, as illustrated in Figure 3. Note how our SizeMode property appears in the Behavior category, shows the ScaleImage setting as the default value (since it isn't in bold), and displays the assigned text in the description pane at the bottom of the window. When you click on the down arrow for this property, the members of the PhotoBoxSizeMode enumeration are displayed to the user.

    Topics for Further Reading
    For further information on custom controls or other topics covered in this article, check out the online documentation and future editions of .NET Developer's Journal. Specific topics related to this discussion include the use of <summary> comments to provide documentation on the members of the control, and the creation of a ControlDesigner class to customize the design-time behavior of a custom control in Visual Studio .NET.

  • In order to post a comment you need to be registered and logged in.

    Register | Sign-in

    Reader Feedback: Page 1 of 1

    Latest Cloud Developer Stories
    Swisscom, the Swiss telecom, is going into the cloud business. Its subsidiary Swisscom IT Services AG has signed up with Red Hat as a Certified Cloud Provider and launched a public cloud Infrastructure-as-a-Service (IaaS) cloud targeting enterprise-class customers primarily in ...
    Apache Deltacloud, the Red Hat-contributed ReSTful API that abstracts differences between clouds so services on any cloud can be managed – provided of course there’s a driver – has graduated from the Apache Foundation’s incubator and is now a full-fledged Top-Level Project (TLP)....
    In a surprise move on Tuesday, January 10, Oracle wheeled out its Big Data Appliance. That’s the one it said in October would be ready sometime in the first half. Only nobody believed it meant early in the first half. Heck, it’s not even clear anybody thought Oracle could make ...
    Rackspace Hosting, the service leader in cloud computing, on Thursday announced its acquisition of SharePoint911, an industry leader in SharePoint consulting, training, and "JumpStart" services within SharePoint. The unification of both companies provides capabilities to deliver ...
    CloudLinux, Inc., on Thursday released CafeFS 3, a virtualized file system for shared hosters that cages each customer within its own virtualized file system. CageFS becomes part of CloudLinux OS at no additional charge. CloudLinux OS, the only commercially-supported Linux OS m...
    Subscribe to the World's Most Powerful Newsletters
    Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
    Click to Add our RSS Feeds to the Service of Your Choice:
    Google Reader or Homepage Add to My Yahoo! Subscribe with Bloglines Subscribe in NewsGator Online
    myFeedster Add to My AOL Subscribe in Rojo Add 'Hugg' to Newsburst from CNET News.com Kinja Digest View Additional SYS-CON Feeds
    Publish Your Article! Please send it to editorial(at)sys-con.com!

    Advertise on this site! Contact advertising(at)sys-con.com! 201 802-3021

    SYS-CON Featured Whitepapers
    ADS BY GOOGLE

    Breaking Cloud Computing News
    As client demand for engagements increases, Revel Consulting (www.revelconsulting.com), a Kirkland, ...