Search code examples
asp.netgridviewwebformscode-behind

how can I know which cell clicked after gridview clicked


I have a PROJECT_EFFORT table.

ProjectId, Year, Month, Effort

1, 2022, 12, 10

2, 2022, 12, 20

2, 2023, 1, 100

2, 2023, 2, 50

2, 2023, 3, 30

3, 2023, 3, 40

3, 2023, 4, 10

3, 2023, 5, 120

4, 2024, 1, 50

...

In a webform, there are 4 dropdownlist start month, start year, end month, end year.

After select start & end - month & year I create datatable and show it on gridview (autogenerated columns).

For example;

-----------------

Start month: 1 

Start year: 2023

End month: 3

End year: 2023


2023.01, 2023.02, 2023.03       

100, 50, 70     

Code behind like this;

(In fact, the logic in the code is a bit complicated and I am simplifying it very much. The columns names are not added hardcoded as below, but they created with a loop according to the selected values.)

...

DataTable dtProjectEffort = new DataTable();

dtProjectEffort.Columns.Add("2023.01");

dtProjectEffort.Columns.Add("2023.02");

dtProjectEffort.Columns.Add("2023.03");

...

//some codes for set values 

...

dtProjectEffort.AcceptChanges();

gvList.DataSource = dtProjectEffort;

gvList.DataBind();

So far I have no problem.

How can I show the details when a value is clicked in gridview.

For example after clicked 70 (under 2023.03) I want show;

Project, Effort

2, 30

3, 40

I need to know which cell was clicked and get its year and month value.


Solution

  • You don't mention if the GridView has autogenerared columns, or the columns are fixed or templated.

    The above detail helps, since if the columns are fixed or tempated, then you can simply add a click event to each control.

    However, let's assume that the columns are auto genreated, and we don't know the number of columns displayed.

    So, there are quite a few options here. Most simple is to "process" the one row on the item data bound event, and add a click event that gets the row and column of the click.

    From the row/column of the click, then we can get/grab the GridView row, and then the column value (cells collection) and thus we have the information to do whatever we want.

    So, say this simple markup:

            <asp:GridView ID="GridView1" runat="server"
                CssClass="table table-hover"
                width="40%" OnRowDataBound="GridView1_RowDataBound"  >
            </asp:GridView>
    
            <asp:HiddenField ID="MyClickValue" runat="server" ClientIDMode="Static" />
            <asp:Button ID="cmdGridClick" runat="server" Text="GridClick"
                OnClick="cmdGridClick_Click" Style="display:none" />
            <script>
                function myclick(sV) {
                    $('#MyClickValue').val(sV)
                    $('#cmdGridClick').click()
                }
            </script>
    

    Note how I added a hidden field (to hold the x,y click value), and a small JavaScript routine. This allows us to run a server side click event after the client side click event for the GridView runs.

    Our server side code is thus this:

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
                LoadGrid();
        }
    
        void LoadGrid()
        {
            string strSQL =
                @"SELECT FirstName, LastName, City, HotelName, Description
                FROM tblHotelsA
                ORDER BY HotelName";
    
            GridView1.DataSource = General.MyRst(strSQL);
            GridView1.DataBind();   
    
        }
    
        protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow) 
            {
                int RowIX = e.Row.RowIndex;
                int i = 0;
                foreach(TableCell OneCell in e.Row.Cells)
                {
                    OneCell.Attributes.Add("OnClick", $"myclick('{RowIX},{i}')");
                    i++;
                }
            }
        }
    
        protected void cmdGridClick_Click(object sender, EventArgs e)
        {
            Debug.Print("Row x, y click = " + MyClickValue.Value);
            string[] xy = MyClickValue.Value.Split(',');            // get actual cell value
            int rowIX = Convert.ToInt32(xy[0]);
            int colIX = Convert.ToInt32(xy[1]);
            GridViewRow gRow = GridView1.Rows[rowIX];
            string MyCellValue = gRow.Cells[colIX].Text;
            Debug.Print("Grid x,y click value = " + MyCellValue);
            Label1.Text = "Value of cell click = " + MyCellValue;
        }
    }
    

    And thus the result is this:

    enter image description here

    So, you can get the x,y value from the grid with above.

    Note that you can thus also translate into your "custom" heading that looks to represent the y axis value of your gird. The GridView header value(s) can be pulled by column value with:

                 GridView1.HeaderRow.Cells[colIX].Text;