Click here to Skip to main content
Click here to Skip to main content
Go to top

Building Interactive Buttons

, 11 Aug 2009
Rate this:
Please Sign up or sign in to vote.
Shows you how to build an interactive button that responds to mouse cursor movements.

Special Thanks

I know it's not common to do so, but I would like to start this article with a special thanks to every MVP in our dear CP especially our valuable Navaneeth..

Don't you think we should have something like MVP of the month?? Anyways, back to the article.

Introduction

Do you like the way commercial applications are designed and ever wondered how come our applications look so dull?? Well, don't worry as this is not your job as a software developer, and usually, it is the job of a professional software designer to handle the UI look and feel of an application in bigger enterprises.

In this article, you will learn a simple technique enabling you to build interactive buttons for your applications that can change their look whenever the mouse cursor is passing over them and change back again to the way they used to look when the mouse cursor leaves.

Interactivity types

We will discuss two types of interactivity in this article:

  1. Resizing the image
  2. Resizing the control

Background

You need to have a basic understanding of the differences between some imaging formats. Here are probably the most important ones you should know about...

JPEG

JPEG (Joint Photographic Experts Group) files are (in most cases) a lossy format; the DOS filename extension is JPG (other Operating Systems may use JPEG). Nearly every digital camera can save images in the JPEG format, which supports 8 bits per color (red, green, blue) for a 24-bit total, producing relatively small files. When not too great, the compression does not noticeably detract from the image's quality, but JPEG files suffer generational degradation when repeatedly edited and saved. Photographic images may be better stored in a lossless non-JPEG format if they will be re-edited, or if small "artifacts" (blemishes caused by the JPEG's compression algorithm) are unacceptable. The JPEG format also is used as the image compression algorithm in many Adobe PDF files.

PNG

The PNG (Portable Network Graphics) file format was created as the free, Open-Source successor to GIF. The PNG file format supports true-color (16 million colors) while GIF supports only 256 colors. A PNG file excels when the image has large, uniformly colored areas. The lossless PNG format is best suited for editing pictures, and lossy formats like JPG are best for the final distribution of photographic images, because JPG files are smaller than PNG files. Many older browsers currently do not support the PNG file format, however, with Mozilla Firefox or Internet Explorer 7, all contemporary web browsers now support all common uses of the PNG format, including full 8-bit translucency (Internet Explorer 7 may display odd colors on translucent images only when combined with IE's opacity filter). The Adam7-interlacing allows an early preview, even when only a small percentage of the image data has been transmitted. PNG is an extensible file format for the lossless, portable, well-compressed storage of raster images. PNG provides a patent-free replacement for GIF, and can also replace many common uses of TIFF. Indexed-color, grayscale, and true-color images are supported, plus an optional alpha channel. PNG is designed to work well in online viewing applications, such as the World Wide Web, so it is fully streamable with a progressive display option. PNG is robust, providing both full file integrity checking and simple detection of common transmission errors. Also, PNG can store gamma and chromaticity data for improved color matching on heterogeneous platforms. Some programs do not handle PNG gamma correctly, which can cause images to be saved or displayed darker than they should be.

GIF

GIF (Graphics Interchange Format) is limited to an 8-bit palette, or 256 colors. This makes the GIF format suitable for storing graphics with relatively few colors, such as simple diagrams, shapes, logos, and cartoon style images. The GIF format supports animation, and is still widely used to provide image animation effects. It also uses a lossless compression that is more effective when large areas have a single color, and ineffective for detailed images or dithered images.

BMP

The BMP file format (Windows bitmap) handles graphics files within the Microsoft Windows OS. Typically, BMP files are uncompressed, hence they are large; the advantage is their simplicity, wide acceptance, and use in Windows programs.

What format should I use?

Now that you know the pros and cons of each image format, let us put it that simple:

  • BMPs: Use uncompressed BMPs when creating your own drawings and keep them as your arts' blue prints of a high quality, maybe in a 24-Bit color mode.
  • JPEGs: Obviously, to compress your bitmaps/other types in the desirable size and quality.
  • GIFs: Use this format to store an animation of image series or to save a small low color logo with transparent parts.
  • PNGs: To store a somewhat compressed better quality image that may also have transparent parts.

Managing resources

It's okay if you're not a graphics designer, you can always reuse something professionals have produced; however, the real challenge will be to find a good set of graphics that look alike and could belong together in one theme (in terms of art and color).

  • Finding resources: Having said that, Google Images is your best source.. Dark blue spheres was our theme in this article. Now that the resources are available, we need to carry out some basic editing so they can fit in our solution.
  • Resizing: You can use the standard Microsoft Office Picture Manager shipped with MS Office 2003 & 2007, or any other image editing application, as this is a very basic feature that must be supported by almost every imaging tool. In MS Picture Manager, zoom in and out to the preferred size and apply that zooming percentage to the resizing option, keeping in mind one of the interactivity types you want to use (see Introduction). I.e., if you decide to resize the image (Option 1), you need to resize your resource image for the smaller size state, otherwise (Option 2), resize your resource image to the larger size state.
  • Adding effects: Now you have the right color and size, you may want to add some text, glow, reflection, shadow, transparency.. etc., or a combination of more than one effect..

For transparency, personally, I would use Adobe Photoshop and do the following:

  1. Open the picture in MS Paint Brush and select the entire picture (Ctrl+A).
  2. Launch Adobe Photoshop "any version will do as we are using one of its most basic features that has been available for so long".
  3. Now that you have the image dimensions in the Clipboard, create a new image (Ctrl+N).
  4. Make sure to select "RGB Color" and 16 bit in the Color Mode box, and most importantly, don't forget to select "Transparent" in the Background Contents box. Also, do not change the width and height of the new image file as they are already matching the dimensions of your image from the Clipboard (the one you copied from MS Paint Brush in step 1).. Click OK.
  5. Paste your image in the new image area with the transparent background.
  6. Now you need to remove the surrounding area of your image. Select the "Magic Wand" tool from the tool box menu on your left and make sure its properties are set properly.
  7. Tolerance: You need to adjust the Tolerance number to the right one according to the difference between the color of your button image and its surroundings.
  8. Check the Anti-aliased option to tell the magic wand to include any insignificant dirt in the selection.
  9. Check the contiguous option selections attached to the click area
  10. You can always hit Ctrl+D to clear the selection if you made a mistake, and Shift+click to add areas to your selection.
  11. Hit the Delete button to remove those surrounding areas and leave your image with a transparent background.
  12. Make sure nothing is selected by hitting Ctrl+D and Save your new image as PNG to avoid loosing the transparency feature, applying some basic compression and still mentain a good color depth.

And you are done! For other effects, I would recommend you to use one of the image effects available in MS PowerPoint 2007 as they are easy and pretty ("well, at least to someone that finds it difficult to draw his own buttons").

Using the code

It is always better to have all the work related to the UI loaded in the InitializeComponent() method, and this is where we are going to store our buttons' interactivity code. The end of the method is always the perfect place to host control events so we can make sure the declaration and initialization of those controls has been previously made above in the method. Note: To find this code, in Form1.cs, right click the InitializeComponent method and choose Go to definition and scroll down for the method's end.

Essential references

First off, you need to include those two libraries as they are not included by default in the standard form designer class:

using System;
using System.Windows.Forms;
using System.Drawing;
  1. Resizing the image:
  2. First, we define the MouseEnter and MouseLeave methods. For MouseEnter, we increase the image size by changing the associated PictureBox control's SizeMode property to the pre-defined enumerator StretchImage so the image fills the control's width and height.

    private void pb_img_MouseEnter(object sender, EventArgs e)
    {
        ((PictureBox)(sender)).SizeMode = PictureBoxSizeMode.StretchImage;
    }

    and to CenterImage so the picture goes back to its original size when the mouse cursor leaves the control...

    private void pb_img_MouseLeave(object sender, EventArgs e)
    {
        ((PictureBox)(sender)).SizeMode = PictureBoxSizeMode.CenterImage;
    }

    And then, assign the relative EventHandler to the buttons (PictureBoxes):

    #region Assigning events for Image Resizing Buttons
    this.pb_img_Reload.MouseEnter += new System.EventHandler(this.pb_img_MouseEnter);
    this.pb_img_Reload.MouseLeave += new System.EventHandler(this.pb_img_MouseLeave);
    
    this.pb_img_Channel.MouseEnter += new System.EventHandler(this.pb_img_MouseEnter);
    this.pb_img_Channel.MouseLeave += new System.EventHandler(this.pb_img_MouseLeave);
    
    this.pb_img_Flash.MouseEnter += new System.EventHandler(this.pb_img_MouseEnter);
    this.pb_img_Flash.MouseLeave += new System.EventHandler(this.pb_img_MouseLeave);
    
    this.pb_img_About.MouseEnter += new System.EventHandler(this.pb_img_MouseEnter);
    this.pb_img_About.MouseLeave += new System.EventHandler(this.pb_img_MouseLeave);
    #endregion

    Note that we assign the same pb_MouseEnter and pb_MouseLeave methods to all the other PictureBoxes as well.

    Also note in this method, the original size of the picture is the one in the CenterImage size mode ("the smaller one"), and that's why you lose some of the quality of the image when enlarged.

  3. Resizing the conrol: As in the image resizing method, we first define the MouseEnter and MouseLeave methods. For MouseEnter, we increase the control size from 24 pixels to 28, i.e., 4 pixels larger, and as the PictureBox control is anchored by default to the upper left corner, we also need to bring it 2 pixels back to that corner (4/2) so it stays centered.
  4. private void pb_ctrl_MouseEnter(object sender, EventArgs e)
    {
        ((PictureBox)(sender)).Size = new Size(28, 28);
        ((PictureBox)(sender)).Location = 
          new Point((((PictureBox)(sender)).Location.X)-2, 
                    (((PictureBox)(sender)).Location.Y)-2);
    }

    And vice versa for the MouseLeave method...

    private void pb_ctrl_MouseLeave(object sender, EventArgs e)
    {
        ((PictureBox)(sender)).Size = new Size(24, 24);
        ((PictureBox)(sender)).Location = 
             new Point((((PictureBox)(sender)).Location.X) + 2, 
                       (((PictureBox)(sender)).Location.Y) + 2);
    }

    And then, assign the relative EventHandler to the buttons (PictureBoxes):

    #region Assigning events for Control Resizing Buttons
    this.pb_ctrl_Reload.MouseEnter += new System.EventHandler(this.pb_ctrl_MouseEnter);
    this.pb_ctrl_Reload.MouseLeave += new System.EventHandler(this.pb_ctrl_MouseLeave);
    
    this.pb_ctrl_Channel.MouseEnter += new System.EventHandler(this.pb_ctrl_MouseEnter);
    this.pb_ctrl_Channel.MouseLeave += new System.EventHandler(this.pb_ctrl_MouseLeave);
    
    this.pb_ctrl_Flash.MouseEnter += new System.EventHandler(this.pb_ctrl_MouseEnter);
    this.pb_ctrl_Flash.MouseLeave += new System.EventHandler(this.pb_ctrl_MouseLeave);
    
    this.pb_ctrl_About.MouseEnter += new System.EventHandler(this.pb_ctrl_MouseEnter);
    this.pb_ctrl_About.MouseLeave += new System.EventHandler(this.pb_ctrl_MouseLeave);
    #endregion

    Note that we assign the same pb_MouseEnter and pb_MouseLeave methods to all the other PictureBoxes as well.

    Also note in this method, the original size of the picture is the one in the MouseEnter event, "the bigger one", and that's why you lose some of the quality of the image when it's small.

Other methods

Of course, there are other methods of doing this, like:

  • Using two sets of images for either states, and the typical way to do it is by using two ImageList controls with a different image dimension for each image set.. If it is your choice, remember to set a high enough color depth for the control so it can support transparency.
  • Using a resource package "like icons" that can contain multiple images with different sizes and quality in one package.
  • Using ImageStrip with some transparency color set, "usually Magenta", specifying the size and boundaries of each image resource.
  • Or using some other developed control that may even have these simple events included in it. A technology like WPF is a perfect example for developing such controls.

Points of interest

Including your code inside the designer's could be a bad practice as VS would automatically rearrange the designer's code in a way that keeps each control's related lines together.

Notice the use of the object sender in the code and the way it is parsed back to its origin from the PictureBox class to avoid naming each object separately:

private void pb_ctrl_MouseEnter(object sender, EventArgs e)
{
    ((PictureBox)(sender)).Size = new Size(28, 28);
    ((PictureBox)(sender)).Location = 
       new Point((((PictureBox)(sender)).Location.X)-2, 
                 (((PictureBox)(sender)).Location.Y)-2);
}
...
this.pb_ctrl_Reload.MouseEnter += new System.EventHandler(this.pb_ctrl_MouseEnter);

A better practice would be to use a referenced object call as follows:

private void pb_ctrl_MouseEnter(ref object sender, EventArgs e)
{
    PictureBox pb = ((PictureBox)(sender))
    pb.Size = new Size(28, 28);
    pb.Location = new Point((pb.Location.X)-2, (pb.Location.Y)-2);
}
...
this.pb_ctrl_Reload.MouseEnter += 
     new System.EventHandler(ref this.pb_img_MouseEnter);

But unfortunately, this is not allowed with event handlers. At least as far as I know, please tell us if you know a way to do it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Muammar©
Retired QSoft
Yemen Yemen
Biography?! I'm not dead yet!
www.QSoftOnline.com

Comments and Discussions

 
QuestionThe is so Good Pinmembergary8751715-May-12 5:24 
wh...
 
Laugh | :laugh:
 
The Code is so Good
 
我是中国人我自豪
GeneralMy vote of 2 PinmemberJared Thirsk24-Aug-09 11:48 
GeneralRe: My vote of 2 Pinmember Muammar©22-Oct-09 0:18 
GeneralMy vote of 1 PinmemberPaul Farry23-Aug-09 3:57 
GeneralRe: My vote of 1 Pinmember Muammar©22-Oct-09 0:20 
GeneralPassing object by reference PinmemberMember 387918218-Aug-09 9:24 
GeneralRe: Passing object by reference PinmemberMuammar©18-Aug-09 9:50 
GeneralMy vote of 1 Pinmemberseeblunt12-Aug-09 5:18 
GeneralRe: My vote of 1 Pinmember Muammar©22-Oct-09 0:19 
GeneralMy vote of 1 PinmemberHan Xiao11-Aug-09 17:08 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140916.1 | Last Updated 11 Aug 2009
Article Copyright 2009 by Muammar©
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid