How to Create .Net DataGridView Image Buttons

As you may have guessed by now, here at Switch On The Code, we are very big advocates of the .Net framework and all it has to offer. Sometimes however, things can be a little bit on the tricky side. Recently I ran into a tricky solution when I was trying to get image buttons in a DataGridView control, and in this tutorial I will go over the solution I came up with, which may just give you the edge the next time you need a fancy DataGridView.

DataGridViews do offer a few different column types, including fairly simple ways to brew up your own custom column types. However, none of the default column types offer a truly good solution for clickable images. What we want here is an image that does something when we click it. Sure we can have a button with an image in it if we use a Button Column, but that is not really what I am looking for. This is where the tricky solution comes in.

For a moment, we have to step back and consider all the options a DataGridView offers, especially the events that can be captured by it. One of these events happens to be CellClick, which is the key to our solution. Using this event we can capture which row and column is clicked, and therefore we can determine if one of our image cells is being clicked. Even better, we can even tell which actual cell was clicked. Using this information we can have image cells that act like buttons, and the best part is that it is not that complicated to get working.

So the first part is pretty strait forward, we need a DataGridView with some image columns. It doesn’t matter what images you use, or how you set up your columns, but you just have to keep track of the column names. Once you have your DataGridView all set up, we need to give it a couple test rows to work with, which we will do during initialization:

public Form1()
{
  InitializeComponent();
  dataGridView1.Rows.Add(5);
}

If you run the project and start clicking away, you will notice that nothing happens when you click on the image cells. This is not what we are after, but with some simple event parsing, we can get a click event going for these cells. In fact, we are going to hook to the CellClick event:

private void dataGridView1_CellClick(
  object sender, DataGridViewCellEventArgs e)
{
  string message = "Row " + e.RowIndex.ToString() + " is ";
 
  //Switch through the column names
  switch (dataGridView1.Columns[e.ColumnIndex].Name)
  {
    case "bug":
      message += "bugging you!";
      break;
    case "chance":
      message += "taking a chance!";
      break;
    case "yes":
      message += "has been marked yes!";
      break;
    case "no":
      message += "has been marked no!";
      break;
  }

  MessageBox.Show(message);
}

Basically what we are doing here is looking for specific columns when a cell is clicked. Technically, in this respect, you could use this method to tell if any specific column is clicked, like a text column as well. However, for this tutorial we just want something to happen when the user clicks on an image cell, and this code does exactly that. When the use clicks on a cell, this event is fired and we check the column of the cell that was clicked. If it is a column we are looking for, we do something, in this case we show a message.

There is one issue with this code though, it fires if ANY cell is clicked, including header cells (row and column headers). This a a fairly big issue, but one that can be fixed very easily. With a simple check, we can fix the problem:

private void dataGridView1_CellClick(
  object sender, DataGridViewCellEventArgs e)
{
  //Do nothing if a header is clicked
  if (e.RowIndex < 0 || e.ColumnIndex < 0)
    return;

  string message = "Row " + e.RowIndex.ToString() + " is ";
 
  //Switch through the column names
  switch (dataGridView1.Columns[e.ColumnIndex].Name)
  {
    case "bug":
      message += "bugging you!";
      break;
    case "chance":
      message += "taking a chance!";
      break;
    case "yes":
      message += "has been marked yes!";
      break;
    case "no":
      message += "has been marked no!";
      break;
  }

  MessageBox.Show(message);
}

With one simple if we now have a solid solution for image buttons in a DataGridView. Each time a cell in one of these columns is clicked, the corresponding message is displayed:

Clicking on an image cell

That is about it for this tutorial. I hope this quick solution helps you in your DataGridView endeavors, and just remember that when you need coding help all you have to do is Switch On The Code.

Leave a Reply

Your email address will not be published. Required fields are marked *