skip to Main Content

e.Row.Cells[2].Text returns an empty string always. I’m trying to delete a row. I want the cell value to pass on to the confirmation text. I don’t know why I’m getting the empty string.Please review the sample code. What mistake I’m doing I don’t know. I tried upto 11, e.Row.Cells[11] – none of the cells have any string value.

 protected void gridView_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                string item = e.Row.Cells[2].Text;
                foreach (Button button in e.Row.Cells[11].Controls.OfType<Button>())
                {
                    if (button.CommandName == "Delete")
                    {
                        button.Attributes["onclick"] = "if(!confirm('Do you want to delete " + item + "?')){ return false; };";
                    }
                }
            }
        }

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:GridView ID="gridView"
                Font-Names="Arial"
                Font-Size="0.75em"
                CellPadding="4" ForeColor="#333333"
                runat="server" AllowPaging="True" DataKeyNames="machine_id" GridLines="None" OnRowDataBound="gridView_RowDataBound" OnRowDeleting="gridView_RowDeleting" AutoGenerateColumns="False" OnPageIndexChanging="gridView_PageIndexChanging">

                <AlternatingRowStyle BackColor="White" />
                <Columns>
                    <asp:TemplateField HeaderText="Machine Id">
                        <ItemTemplate>
                            <%#Eval("machine_id")%>
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="Machine Name">
                        <ItemTemplate>
                            <%#Eval("machine_name")%>
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="Image Name">
                         <ItemTemplate>
                            <%#Eval("imagename")%>
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="Image Type">
                         <ItemTemplate>
                            <%#Eval("imagetype")%>
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="Image data">
                         <ItemTemplate>
                            <%#Eval("imagedata")%>
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="Description">
                         <ItemTemplate>
                            <%#Eval("description")%>
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="Line">
                         <ItemTemplate>
                            <%#Eval("line")%>
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="Category">
                         <ItemTemplate>
                            <%#Eval("category")%>
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="Location">
                         <ItemTemplate>
                            <%#Eval("location")%>
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="Serial No">
                         <ItemTemplate>
                            <%#Eval("serial_no")%>
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="Plant Name">
                         <ItemTemplate>
                            <%#Eval("plant_name")%>
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:CommandField ButtonType="Button" ShowDeleteButton="True" />
                </Columns>
                <EditRowStyle BackColor="#2461BF" />
                <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />

                <HeaderStyle BackColor="#507CD1" ForeColor="white" Font-Bold="True" />

                <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" />
                <RowStyle BackColor="#EFF3FB" />
                <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" />
                <SortedAscendingCellStyle BackColor="#F5F7FB" />
                <SortedAscendingHeaderStyle BackColor="#6D95E1" />
                <SortedDescendingCellStyle BackColor="#E9EBEF" />
                <SortedDescendingHeaderStyle BackColor="#4870BE" />

            </asp:GridView>
        </div>
    </form>
</body>
</html>

2

Answers


  1. You can read it from data-source:

    string item = (string)DataBinder.Eval(e.Row.DataItem, "Machine Name");
    
    Login or Signup to reply.
  2. Ok, so a few things:

    The cells[] collection only works for NON templated columns.

    So, say, take this example GridView.

    <asp:GridView ID="GVHotels" runat="server" AutoGenerateColumns="False"
        DataKeyNames="ID" CssClass="table table-striped table-hover"
        Width="50%">
        <Columns>
            <asp:BoundField DataField="FirstName" HeaderText="FirstName" />
            <asp:BoundField DataField="LastName" HeaderText="LastName" />
            <asp:BoundField DataField="City" HeaderText="City" />
            <asp:BoundField DataField="HotelName" HeaderText="HotelName" />
            <asp:BoundField DataField="Description" HeaderText="Description" />
            <asp:TemplateField HeaderText="Hotel2">
                <ItemTemplate>
                    <asp:Label ID="lblHotel" runat="server"
                        Text='<%# Eval("HotelName") %>'>
                    </asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Delete">
                <ItemTemplate>
                    <asp:Button ID="cmdMyDelete" runat="server" Text="Delete"
                        OnClick="cmdMyDelete_Click"
                        OnClientClick='<%#  $@"return confirm(""delete Hotel = {Eval("HotelName")}"")"   %>' />
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>
    

    So, in above, I for this example have the HotelName placed 2 times in the GridView.

    So, the rules are:

    Databound = cells[] collection.

    TemplateFields = FindControl.

    So, cells[] collection can’t be used in your case.

    However, worse yet?

    You using templated columns, but are NOT using standard controls with a runat=server, and ALSO an "id". Both of these are required when using templated columns.

    Since you not using standard controls in your templated columns?

    Then do NOT use them unless you need or want a standard control. Use BoundField, since that is LESS markup, less effort, and allows you to use the cells[] collection to get data values from that given row.

    Also, note that you are 100% free to use sever side expressions in the markup.

    So, in above, we have a confirmation click event added to that button (and also the server side click).

    So, then this:

    <asp:TemplateField HeaderText="Delete">
        <ItemTemplate>
            <asp:Button ID="cmdMyDelete" runat="server" Text="Delete"
                OnClick="cmdMyDelete_Click"
                OnClientClick='<%#  $@"return confirm(""delete Hotel = {Eval("HotelName")}"")"   %>' />
        </ItemTemplate>
    </asp:TemplateField>
    

    So, note in above, we placed the JavaScript confirm code inside of the client click event.

    So, code to load is thus cells [:

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
                LoadData();
        }
    
        void LoadData()
        {
            GVHotels.DataSource = 
                General.MyRst("SELECT * FROM tblHotelsA ORDER BY HotelName");
            GVHotels.DataBind();
        }
    

    And the delete button code is this:

        protected void cmdMyDelete_Click(object sender, EventArgs e)
        {
            Button btn = (Button)sender;
            GridViewRow gRow = (GridViewRow)btn.NamingContainer;
    
            int PK = Convert.ToInt32(GVHotels.DataKeys[gRow.RowIndex]["ID"]);
    
            Debug.Print($"Row index click on = {gRow.RowIndex}");
            Debug.Print($"Database PK id = {PK}");
    
            // get hotel name from cells (data bound only)
            Debug.Print($"Hotel name = {gRow.Cells[3].Text}");
    
            // get hotel from templated column
            Label lblHotel = (Label)gRow.FindControl("lblHotel");
            Debug.Print($"Hotel name from templated column  = {lblHotel.Text}");
    
            // delete this reocrd....
            SqlCommand cmdSQL = 
                new SqlCommand("DELETE FROM tblHotelsA WHERE ID = @ID");
    
            cmdSQL.Parameters.Add("@ID", System.Data.SqlDbType.Int).Value = PK;
            General.MyRstE(cmdSQL);
    
            LoadData();   // refresh grid view
    
        }
    

    So, the actual delete code is only the last 3 lines of above, but the code shows how to get data bound columns (cells[] collection).

    And code shows how to get templated columns (FindControl and the control in the template MUST have "id" and control MUST have runat="server").

    Also note how the standard button click event can obtain use of the current row click. Use of NamingContainer works for GridView, Repeater, ListView and in fact all of the data aware (bindable) controls. This quite much suggests that you really in most cases don’t need or want to use the built in events of the GridView.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search