3

I asked this question regarding a strange behaviour from a GridView control in ASP.Net (I'm using C#).

For each row in my GridView there is an an 'Edit' and 'Delete' link. The edit for example has this javascript:__doPostBack('gvwServers','Edit$0') - So obviously the server is going to figure out someone has clicked to edit row 0 of gvwServers.

Fair enough. If I click the Edit link I get a postback and the GridView is redrawn with the Edit button replaced with an 'Update' and 'Cancel' button. Standard behaviour. NOW - The 'Cancel' button has this link javascript:__doPostBack('gvwServers','Cancel$0') - just what I would expect Cancel row 0 of gvwServers. BUT The Update button has javascript:__doPostBack('gvwServers$ctl02$ctl00',''). This appears to not make any sense. And this appears to be the cause of my routine to handle Update not being fired.

Why is ASP not outputting the correct postback arguments?

My code is available at the link above.

<asp:GridView ID="gvwServers" runat="server" class="gvwServers"  
AutoGenerateColumns="false"  OnRowEditing="gvwServers_Edit" 
onrowcancelingedit="gvwServers_Cancelling" onrowdeleting="gvwServers_Deleting" 
onrowupdated="gvwServers_Updated" onrowupdating="gvwServers_Updating"
AutoGenerateEditButton=true AutoGenerateDeleteButton=true>

<columns>
    <asp:CommandField  ShowEditButton="true" />
    <asp:CommandField  ShowDeleteButton="true" /> 
    <asp:BoundField DataField="intServerID" visible="false" />

    <asp:TemplateField HeaderText = "Server Name">
        <ItemTemplate>
            <asp:Label ID="lblServerName" runat="server" Text='<%# Bind("txtName") %>'></asp:Label>
        </ItemTemplate>
        <EditItemTemplate>
            <asp:TextBox ID="txtServerName_Edit" runat="server" Text='<%# Bind("txtName") %>'></asp:TextBox>
        </EditItemTemplate>
    </asp:TemplateField>

    <asp:TemplateField  HeaderText = "Key">
        <ItemTemplate>
            <asp:Label ID="lblAppKey" runat="server" Text='<%# Bind("txtApplicationKey") %>'></asp:Label>
        </ItemTemplate>
        <EditItemTemplate>
            <asp:TextBox ID="txtAppKey_Edit" runat="server" Text='<%# Bind("txtApplicationKey") %>'></asp:TextBox>
        </EditItemTemplate>
    </asp:TemplateField>

    <asp:TemplateField  HeaderText = "Connection String">
        <ItemTemplate>
            <asp:Label ID="lblConnString" runat="server" Text='************'></asp:Label>
        </ItemTemplate>
        <EditItemTemplate>
            <asp:TextBox runat="server" ID="txtConnString_Edit" Width="300px" Height="100px" Text='<%# Bind("txtConnectionString")%>' TextMode="MultiLine" ></asp:TextBox>
        </EditItemTemplate>
    </asp:TemplateField>

</columns>
</asp:GridView> 
Community
  • 1
  • 1
El Ronnoco
  • 11,753
  • 5
  • 38
  • 65

1 Answers1

2

Not sure what you're expecting/not happening. I took your gridview code and used your code behind in the other link. I added a Response.Write in each handler and it seems to run as expected.

public class Item
{
    public int intServerID { get; set; }
    public string txtName { get; set; }
    public string txtApplicationKey { get; set; }
    public string txtConnectionString { get; set; }
}

protected void Page_Load(object sender, EventArgs e)
{
    Item item = new Item();
    item.intServerID = 1;
    item.txtName = "Apple";
    item.txtApplicationKey = "Orange";
    item.txtConnectionString = "Test";

    List<Item> items = new List<Item>();
    items.Add(item);

    gvwServers.DataSource = items;
    gvwServers.DataBind();
}

protected void gvwServers_Edit(object sender, GridViewEditEventArgs e)
{
    Response.Write("Edit");
    gvwServers.EditIndex = e.NewEditIndex;
    gvwServers.DataBind();
}
protected void gvwServers_Updated(object sender, GridViewUpdatedEventArgs e)
{
    Response.Write("Updated");
    gvwServers.DataBind();
}

protected void gvwServers_Updating(object sender, GridViewUpdateEventArgs e)
{
    Response.Write("Updating");
    gvwServers.DataBind();
}
protected void gvwServers_Deleting(object sender, GridViewDeleteEventArgs e)
{
    Response.Write("Delete");
    gvwServers.DataBind();
}
protected void gvwServers_Cancelling(object sender, GridViewCancelEditEventArgs e)
{
    Response.Write("Cancel");

    e.Cancel = true;
    gvwServers.EditIndex = -1;
    gvwServers.DataBind();
}
Wil
  • 2,328
  • 2
  • 20
  • 27
  • Does the gvwServers_Updating routine fire? Can you see what the __doPostBack arguments are when hovering over the Update button? – El Ronnoco Feb 01 '11 at 15:00
  • The reason (I think) that I've marked this answer as correct is that the method of populating the datagrid is correct ie in `Load` - I was doing it in `Init`. This must have somehow been breaking the handler association. Can you shed any light on that one? – El Ronnoco Feb 01 '11 at 15:24
  • Init only runs on the first load, not on any subsequent postbacks – Wil Feb 01 '11 at 15:28
  • @Wil Yes, I know that and that's why I was populating the datagrid on init. It doesn't explain why it was breaking the update event. I think maybe because the control referenced in the __doPostBack argument was no longer present and so could not be located or something?? – El Ronnoco Feb 01 '11 at 15:38
  • 2
    It has to do with the life cycle of asp.net. If you are loading the grid again in the init, there is no access to the viewstate ie telling the page that you are in edit mode. – Wil Feb 01 '11 at 16:11
  • +1 to everyone! I had this problem too and was getting quite frustrated trying to figure out why it stopped working. Turns out I had moved the gridview population to init as well. – Yetti Aug 25 '11 at 22:05