Home > OS >  Asp.Net WebForms Gridview OnRowCommand Event not hitting code behind method
Asp.Net WebForms Gridview OnRowCommand Event not hitting code behind method

Time:11-24

I am trying to incorporate an edit button in a grid view. However the on row command does not seem to be firing. I put a break point on the onrowcommand method i have implemented in the code behind.

Here is the View (i substituted the imageurl with xxx's as privacy concern on here):

    <asp:GridView ID="GridViewContacts1" runat="server" CssClass="data_table" AutoGenerateColumns="false" OnRowCommand="GridViewContacts1_OnRowCommand" EmptyDataText="There are no contacts for this prospect." >
    <AlternatingRowStyle CssClass="alternating_row" />
    <Columns>
        <asp:BoundField DataField="ContactName" HeaderText="Name" />
        <asp:BoundField DataField="ContactTitle" HeaderText="Title" />
        <asp:TemplateField HeaderText="Phone" SortExpression="PhoneNumber">
            <ItemTemplate>
                <%# FormatPhone(Eval("PhoneNumber").ToString()) %>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:BoundField DataField="Email" HeaderText="Email" SortExpression="Email"></asp:BoundField>
        <asp:TemplateField HeaderText="Edit" ItemStyle-HorizontalAlign="Center">
            <ItemTemplate>
                <asp:ImageButton ID="icmdEditContact" Runat="server" ImageUrl="xxxxx" BorderStyle="None" CommandName="EditContact" CommandArgument='<%# Eval("ContactId") %>'/>
            </ItemTemplate>
        </asp:TemplateField>
    
        <asp:TemplateField HeaderText="Delete" ItemStyle-HorizontalAlign="Center">
            <ItemTemplate>
                <asp:LinkButton  CommandArgument='<%# Eval("ContactId") %>' CausesValidation="false" CommandName="DeleteItem" OnClientClick="javascript:return confirm('Are you sure you want to delete this record?')" Runat="server" ID="Linkbutton1"><img src="xxxxx" border="0"/></asp:LinkButton>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

As you will see the OnRowCommand Property of the grid view is : GridViewContacts1_OnRowCommand

Here is the code behind enter image description here

The problem i'm having is this isn't getting hit : enter image description here

Any ideas or suggestions ?

I even tried to incorporate without the rowcommand by just using a normal button and click event and it still wouldn't hit the designated codebehind method for that click event. enter image description here

enter image description here

CodePudding user response:

Do both buttons not work, or just the delete button?

Make sure viewstate is not turned off for the GV, and "always" give each button a "id" - your delete button is missing one.

On the other hand?

I often, and in fact BEYOND often just dump the built in commands for the GV. You actually don't need them.

For any button, image button etc that you drop into your GV (templated column), then you can just add/use/have a plain jane click event, and then use that.

The "bonus" then is you are free to add new buttons, and you don't have to use nor mumble jumpble all of the commands into that one on-row command routine anyway.

So, do check:

 make sure view state of gv not turned off
 make sure each button has a "id"
 make sure you not re-binding the gv on page load each time
 (you look to have the all important !IsPostback (good).

However, as noted, I don't use the row commands anymore.

You can do it this way:

Say this GV.

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" 
    DataKeyNames="ID"  width="40%" CssClass="table table-hover" >
    <Columns>
        <asp:BoundField DataField="FirstName" HeaderText="FirstName"  />
        <asp:BoundField DataField="LastName" HeaderText="LastName"  />
        <asp:BoundField DataField="HotelName" HeaderText="HotelName"  />
        <asp:BoundField DataField="Description" HeaderText="Description"  />
        <asp:TemplateField HeaderText="Active" ItemStyle-HorizontalAlign="Center">
            <ItemTemplate>
                <asp:CheckBox ID="chkActive" runat="server" 
                    Checked='<%# Eval("Active") %>'/>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField>
            <ItemTemplate>
                <asp:Button ID="cmdView" runat="server" Text="View" CssClass="btn"
                    OnClick="cmdView_Click" />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

And code to load:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
            LoadGrid();
    }

    void LoadGrid()
    {
        using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
        {
            string strSQL = 
                @"SELECT * FROM tblHotelsA ORDER BY HotelName";
            using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
            {
                conn.Open();
                DataTable rstData = new DataTable();
                rstData.Load(cmdSQL.ExecuteReader());
                GridView1.DataSource = rstData;
                GridView1.DataBind();
            }
        }
    }

And we see/get this:

enter image description here

Button click code - each button is SEPERATED - nice!!

So, this code:

    protected void cmdView_Click(object sender, EventArgs e)
    {
        Button btn = (Button)sender;
        GridViewRow gRow = (GridViewRow)btn.NamingContainer;

        int iPK = (int)GridView1.DataKeys[gRow.RowIndex]["ID"];
        Debug.Print("Database PK = "   iPK);

        Debug.Print("Row index click = "   gRow.RowIndex);
        Debug.Print("Hotel Name = "   gRow.Cells[3].Text);   // non template values

        // get value of check box control on this row
        CheckBox chkActive = (CheckBox)gRow.FindControl("chkActive");
        Debug.Print("Value of active check box control = "   chkActive.Checked);

        // hide gv, show edit area.
        // bla bla bal
    }

Now clicking on a button, we get this output:

Database PK = 16
Row index click = 0
Hotel Name = Batman's Cave
Value of active check box control = True

So, Note how we use database "datakeys" option. This is VERY improant for secuirty, since the database row PK is NEVER exposted client side.

However, as above shows:

 You can easy get the datakeys (row PK id)
 You can easy get the row index
 you have full use of the row (namingcontainer)
 you can use find control etc.

So, really, I see LITTLE reason to use the built in row index command.

You ARE free to add/use/have/enjoy the command arugument for a button, or image button, or link buttion and I'll often use that to add/supply extra information to pass to the button).

But for the public and history?

Check viewestate, add "id" to those buttons that don't have one.

However, all in all, since you can just use/add/have a button click like any other button you drop into a page, then I just continue to use simple plain jane button clicks, and not bother with the GV event model.

Note that naming container trick used above works for repeaters/listview/datalist etc.

  • Related