Change a DataGridView entry when the user double-clicks a cell in C#


This post is in response to the following question:

Respected Sir,

I need help on how can i change the datagridview cell value by double click on that cell.

Let say cell contain value ‘N’ when i double click it will change to ‘Y’ .

First, note that by default the DataGridView control allows the user to edit its data. If you click on a DataGridView cell and then click on the cell again, the control allows you to edit that cell’s value. For example, see my post Build a DataTable and bind it to a DataGridView in C#.

For the question to make sense, we must have disabled the control’s natural editing capabilities. This example does that in its Form_Load event handler shown shortly. It then detects double-clicks and takes action depending on the cell that was clicked.

To make it easier for the user to know that particular cells are double-clickable, the program changes the cursor for those cells.

The following sections describe the pieces of the program that accomplish those tasks.


The following code shows the form’s Load event handler.

private void Form1_Load(object sender, EventArgs e)
    // Make the DataTable object.
    DataTable dt = new DataTable("Books");

    // Add columns to the DataTable.
    dt.Columns.Add("Has Download",
    // Add items to the table.
    dt.Rows.Add(new object[] { "Essential Algorithms", ... );
    dt.Rows.Add(new object[] { "WPF 3d", true, "2018", ... );
    dt.Rows.Add(new object[] { "The C# Helper Top 100", ... );
    dt.Rows.Add(new object[] { "Interview Puzzles Dissected", ... );

    // Make the DataGridView use the DataTable as its data source.
    dgvBooks.DataSource = dt;

    // Draw URLs in a blue, underlined font.
        new Font(dgvBooks.Font, FontStyle.Underline);
    dgvBooks.Columns["URL"].DefaultCellStyle.ForeColor =

    // Set column widths.

    // Do not allow automatic editing.
    dgvBooks.EditMode = DataGridViewEditMode.EditProgrammatically;
    dgvBooks.AllowUserToAddRows = false;
    dgvBooks.AllowUserToDeleteRows = false;

This code creates a DataTable to hold the data. It adds columns of different data types and then inserts data into the table.

Next, the program sets the DataGridView control’s DataSource property to the DataTable. At this point, the control allows the user to view and edit the data.

Next, the program sets the font for the DefaultCellStyle property in the URL column. It sets that property to a new font that is based on the DataGridView control’s font but with the underline style. That makes the values in that column appear underlined.

Similarly, the code sets the URL column’s default cell style to draw blue text so the URL values are drawn with a blue, underlined font.

The code then calls the DataGridView control’s AutoResizeColumns method to make the columns size themselves to fit their data.

Finally, the Load event handler sets the control’s EditMode so the user cannot edit the data value. It also prevents the user from adding new records or deleting existing ones.

Changing Cursors

When the mouse enters a cell, the following event handler sets the appropriate cursor.

// Display an appropriate cursor in the Has Download and URL columns.
private void dgvBooks_CellMouseEnter(object sender,
    DataGridViewCellEventArgs e)
    int col = e.ColumnIndex;
    if (col == -1) return;

    if (dgvBooks.Columns[col].Name == "Has Download")
        dgvBooks.Cursor = Cursors.Hand;
    else if (dgvBooks.Columns[col].Name == "URL")
        dgvBooks.Cursor = Cursors.UpArrow;

This event handler checks the column number below the mouse. If the mouse is to the left of the first column of data, then the column number is -1. In that case, the method exits. If the mouse is below the DataGridView control’s last row or to the right of the rightmost column, then this event is not raised.

If the column number is at least 0, the code checks the name of the column. If this is the Has Download column, the code sets the control’s cursor to Hand. If this is the URL column, the code sets the control’s cursor to UpArrow.

When the mouse moves off of a column, the following event handler executes.

// Restore the default cursor..
private void dgvBooks_CellMouseLeave(object sender,
    DataGridViewCellEventArgs e)
    if (dgvBooks.Cursor != Cursors.Default)
        dgvBooks.Cursor = Cursors.Default;

This code simply checks the DataGridView control’s current cursor and resets it to the default if it is not already the default.

Modifying Values

When the user double-clicks on a cell, the following event handler executes.

// Toggle the Has Download field. Open the URL.
private void dgvBooks_CellDoubleClick(object sender,
    DataGridViewCellEventArgs e)
    int col = e.ColumnIndex;
    if (col == -1) return;

    int row = e.RowIndex;

    // See which column this is.
    if (dgvBooks.Columns[col].Name == "Has Download")
        // Toggle the value.
        bool value = (bool)dgvBooks.Rows[row].Cells[col].Value;
        dgvBooks.Rows[row].Cells[col].Value = !value;
    else if (dgvBooks.Columns[e.ColumnIndex].Name == "URL")
        // Open the URL.
        string url = (string)dgvBooks.Rows[row].Cells[col].Value;

This code verifies that the column number is at least 0 as before. If user double-clicked the Has Download column, the code gets the current value in the clicked cell and then updates the cell to hold the opposite of that value.

If the user double-clicked the URL column, the program gets the value in the cell and then uses System.Diagnostics.Process.Start to “start” the URL. That launches the URL in the system’s default browser.


I generally don’t recommend that you write your own code to edit DataGridView data because that control already does a pretty good job. Still, it may sometimes be useful to provide custom editing of some sort such as allowing the user to toggle a value as in this example.

An alternative might be to prevent editing in columns that the user should not modify. For example, the following statement prevents the user from editing the values in the first column.

dt.Columns[0].ReadOnly = true;

Download the example to see the code and to experiment with the program.

Download Example   Follow me on Twitter   RSS feed   Donate

About RodStephens

Rod Stephens is a software consultant and author who has written more than 30 books and 250 magazine articles covering C#, Visual Basic, Visual Basic for Applications, Delphi, and Java.
This entry was posted in controls, database, user interface and tagged , , , , , , , , . Bookmark the permalink.

5 Responses to Change a DataGridView entry when the user double-clicks a cell in C#

  1. Nikos says:

    Hi and thank you for these great tutorials! Your tutorials helped me a lot! Could you please create a tutorial for the Licensing system with GUI management? To manage the users, ban the user or extend the license period?

    • RodStephens says:

      Sorry but I don’t know how to use Microsoft’s licensing system. I think Microsoft intends you to use a third party tool.

      There is this example if you want to try to make your own.

      Register a program for a particular system in C#

      • NIKOS says:

        no, I do not mean Microsoft’s licensing system, I mean if you can make a GUI for the C# program you have , to manage the user’s.

        • RodStephens says:

          Well, that example does have a simple interface. The KeyMaker program generates the keys. You would run that program to create the customer key. The CustomerProgram example is for the user.

          It doesn’t have any kind of database to keep track of customers. You could add one, although I would be tempted to just store the customers’ IDs and keys in a spreadsheet.

          It’s also not a super bullet-proof system. A decent hacker could probably work around it. And it doesn’t have a way to block a user. You could store a code somewhere in the registry, but again a hacker could probably find it if determined enough.

          It does have the advantage that the product is bound to a particular system so multiple users couldn’t share keys. (Which I think is fairly common, or at least it used to be.)

          It seems like ClickOnce (and maybe UWP) might provide a method that’s better. If you require the app to check for updates, you could make the update include data allowing or denying access to particular systems. That would only work if the number of systems is relatively small. (You wouldn’t want every user to need to constantly download a huge amount of data.) But I haven’t done this. It’s starting to get out of my areas of experience.

          • RodStephens says:

            After further thought, it occurred to me that you could make the program itself download a file from your web site. That file could list (probably encrypted) the serial numbers of computers that are allowed to run the program. The program could check the file’s modification time first so it doesn’t need to download the file every time.

Comments are closed.