Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#4.0

Simple Bitmap Buttons for WinForm Applications

6 May 2014CPOL3 min read 21.1K   515  
This describes a simple way to create interactive, bitmap based, buttons for WinForm applications.

Introduction

With this article, i want to describe a very simple way to create interactive bitmap buttons for WinForm applications. The problem was, that WinForm doesn't supply a decent way to create bitmap buttons. At least not for lag free applications.

The first thing that everyone had at least tried once, is the approach over a flat Button, but sooner or later ran into some styling issues, the image wasn't correctly placed, etc... At least this was a big problem for me.

Next up was a PictureBox, it worked... but somehow there was a slight delay until the image was changed into the proper one. Ok, you might say thats a small issue and it wont stick out as much. But this is a huge issue for high quality applications.

So, to eliminate the "lag", i decided to use a ImageList for my bitmaps and like magic, the issue was gone. And on the plus side, it doesn't take much work to use this method.

Using the code

As usual, we start with a new solution in VS and chose C# -> Windows Forms-Application as our project type. Within the draft-mode of Form1, we switch to the event pane and double click on Behavior -> Load. This should generate the following code within the Form1.cs:

C#
using System;
using System.Drawing;
using System.Windows.Forms;

namespace Application
{
    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            
        }

    }
} 

We leave this as it is, at least for now.

Now we add a PictureBox to Form1 in draft mode. Leave everything as it is, except the Size and SizeMode. For the Size we enter the size of our bitmap and we set the SizeMode to CenterImage.

At this point we should add our bitmap to the resources. In total 3 bitmaps for the states normal, hover and down. If you don't know how to add resources to your project, you should read this article on MSDN: Adding and Editing Resources (Visual C#)

Now on to the Form1.cs, there we add a new property of the ImageList type and initialize right away.

C#
using System;
using System.Drawing;
using System.Windows.Forms;

namespace Application
{     
    public partial class Form1 : Form
    {

        // New Property
        private ImageList _btnImage = new ImageList();

        public Form1()
        {
            InitializeComponent();
        }
        //...
    }
}  

What is an ImageList?

Basically it is an array of images, but the object itself contains some additional data, like ColorDepth and Size. Both should be specified before you add images, otherwise you can run into some problems.

Also it provides a consistent way to store and access images with different states, like buttons.

After we defined and initialized the ImageList, we can now add all the images and define the ColorDepth and Size.

C#
//...
namespace Application
{
    public partial class Form1 : Form
    {

        private ImageList _btnImage = new ImageList();
        //...

        private void Form1_Load(object sender, EventArgs e)
        }
            // Defining Image Metrics
            this._btnImage.ImageSize = new Size(26, 26); // Image Size
            this._btnImage.ColorDepth = ColorDepth.Depth32Bit; // Image ColorDepth

            // Adding Images
            this._btnImage.Images.Add("normal", Resources.NormalImage);
            this._btnImage.Images.Add("hover", Resources.HoverImage);
            this._btnImage.Images.Add("down", Resources.DownImage);

            // Assigning Default Image to the "Button"
            this.ImageButton.Image = this._btnImage.Images["normal"];

        }

    }
}  

The rest if relatively straight forward, so i won't go into the details.

C#
//...
namespace Application
{
    public partial class Form1 : Form
    {
        //...

        // Hover
        private void ImageButton_MouseEnter(object sender, EventArgs e)
        {
            this.ImageButton.Image = this._btnImage.Images["hover"];
        }

        // Reset
        private void ImageButton_MouseLeave(object sender, EventArgs e)
        }
            this.ImageButton.Image = this._btnImage.Images["normal"];
        }

        // Down
        private void ImageButton_MouseDown(object sender, MouseEventArgs e)
        {
            if(MouseButtons.Equals(MouseButtons.Left, e.Button))
            {
                this.ImageButton.Image = this._btnImage.Images["down"];
            }
        }

        // Up
        private void ImageButton_MouseUp(object sender, MouseEventArgs e)
        {
            if(MouseButtons.Equals(MouseButtons.Left, e.Button))
            {
                this.ImageButton.Image = this._btnImage.Images["hover"];
            }
        }

        // Click
        private void ImageButton_Click(object sender, EventArgs e)
        {
            // Do Something
        }

    }
}  

Now you just have to assign the corresponding methods, to the PictureBox events. Keep in mind, that i renamed the PictureBox to ImageButton for this example, you have to use the name you entered in the Name field.

Points of Interest

On the first look it seems like quite a lot of work, just to make one bitmap button. But if you're using the same bitmap all over the place, you'll find this method quite simple and time saving. Especially if you use the same basic image, but with different states.

There is one thing you should keep in mind, you definitely have to define the ColorDepth, otherwise the image will be rendered in the lowest available ColorDepth and that can result in funny renderings.

History

First release.

License

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