1

I have a LinkButton inside a GridView that passes a CommandArgument and tries to fire RowCommand

GridView declaration:

<asp:GridView PageIndex="0" OnRowCommand="GridView1_RowCommand" PageSize="10" AllowPaging="true" OnPageIndexChanging="GridView1_PageIndexChanging"
ID="GridView1" runat="server" BackColor="White" BorderColor="#CCCCCC" BorderStyle="None"
BorderWidth="1px" CellPadding="4" ForeColor="Black" GridLines="Horizontal" Width="700px"
AutoGenerateColumns="False" OnPageIndexChanged="GridView1_PageIndexChanged">

LinkButton inside the GridView:

<asp:TemplateField>
    <ItemTemplate>
        <asp:LinkButton ID="LinkButton1" OnClientClick="return confirm('Are you sure you want to delete this checklist?');" runat="server" CausesValidation="false" CommandName="DeleteChecklist" CommandArgument='<%# Eval("refID") %>' Text="Delete"></asp:LinkButton>
    </ItemTemplate>
    <ItemStyle ForeColor="Black" />
    <ControlStyle BorderStyle="None" ForeColor="Black" />
</asp:TemplateField>

Code behind:

protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
    if (e.CommandName == "DeleteChecklist")
    {
        string refID = e.CommandArgument.ToString();
        DAL.DeleteChecklist(refID);
     }
}

I placed a breakpoint at RowCommand but it doesn't get fired at all, any idea why?

dythe
  • 840
  • 5
  • 21
  • 45

3 Answers3

3

I assume that you're databinding the GridView on postbacks. So always embed it in a if(!IsPostBack) check:

protected void Page_Load(Object sender, EventArgs e)
{
    if(!IsPostBack)
    {
         GridView1.DataSource = getSource();
         GridView1.DataBind();
    }
}

Otherwise events won't be triggered and edited values will be overridden.

Another possible reason: Have you disabled ViewState?

Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • @dythe: What means that you _"tried that"_? You _must_ do it this way even if it does not solve your issue. Then it would be your next issue ;) Have you seen my note about ViewState? – Tim Schmelter Dec 05 '12 at 09:39
  • Nope, doesn't work too for ViewState and for the method you mentioned, i placed it in my code and it still doesn't work. – dythe Dec 05 '12 at 09:39
  • @dythe: Again, what means that you _"tried it"_? 1.) Is ViewState enabled? 2.) What code is in `Page_Load`? – Tim Schmelter Dec 05 '12 at 09:40
  • 1) yes 2) i binded my datasource in Page_Load like how you did it. – dythe Dec 05 '12 at 09:42
  • By the way, does the `LinkButton` post back at all? – Tim Schmelter Dec 05 '12 at 09:42
  • Ok, i solved it by using if(IsPostBack) and then binding my datasource instead, no idea why it is working like that tho. – dythe Dec 05 '12 at 09:44
  • @dythe: You have solved it by binding the GridView only on postbacks and not at the first time? That makes no sense at all. – Tim Schmelter Dec 05 '12 at 09:48
  • Could it be because i'm not binding the GridView on Page_Load and only after the user clicks the Search Button? – dythe Dec 05 '12 at 09:49
  • You haven't mentioned that you're binding it from a search button. That cannot cause your issue but then it makes no sense to bind it from `Page_Load` (of course). – Tim Schmelter Dec 05 '12 at 09:52
1

EDIT2: Ok it got better. You can make it work with AllowCustomPaging="true" but the property VirtualItemCount must have to be greater than the PageSize value of your grid view. Look at this:

<asp:GridView runat="server" ID="gvPresupuestos" AutoGenerateColumns="False" 
    OnRowCommand="gvPresupuestos_RowCommand" 
    OnPageIndexChanging="gvPresupuestos_PageIndexChanging" 
    OnPreRender="gvPresupuestos_PreRender" ItemType="Core.NominaEntities.TipoPresupuesto" 
    AllowPaging="true" PageSize="1" AllowCustomPaging="true"
    UseAccessibleHeader="true" GridLines="None" CssClass="table table-hover" 
    ShowHeaderWhenEmpty="True">
    <Columns>
        <asp:BoundField HeaderText="Nombre del presupuesto" DataField="Nombre" />
        <asp:TemplateField HeaderText="Opciones">
            <ItemTemplate>
                <a href='<%# "Detalle?p=" + Item.IdTipoPresupuesto.ToString() %>' 
                    target="_self"><%# Item.Editable ? "Editar" : "Ver" %></a>
                <asp:LinkButton runat="server" 
                    CommandArgument='<%# Item.IdTipoPresupuesto.ToString() %>' 
                    CommandName="Deshabilitar" 
                    Text="Deshabilitar" Visible='<%# !Item.Editable ? true : false %>' />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

FillView() method:

private void FillView(int desiredPage)
{
    var cliente = ClientFactory.CreateAuthServiceClient();
    using (cliente as IDisposable)
    {
        // this list only has 1 item.
        List<TipoPresupuesto> resultado = cliente.ObtenerTiposDePresupuesto();
        gvPresupuestos.DataSource = resultado;
        // For testing pursposes, force the virtual item count to 1000.
        gvPresupuestos.VirtualItemCount = 1000;
        gvPresupuestos.DataBind();
    }
}

So, the LinkButton does not fire the gvPresupuestos_RowCommand event unless the virtual item count is greater than the VirtualItemCount property.

I hope this helps.

EDIT1: I found it. You can make it work by changing the value of "AllowCustomPaging" to false. I don't know why, but hope this can help.

ORIGINAL 'ANSWER':

I have the same problem. You can see the my code here:

<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<div class="jumbotron jumbotron-small">
    <h2>Presupuestos</h2>
</div>

<asp:GridView runat="server" ID="gvPresupuestos" 
AutoGenerateColumns="False" AllowPaging="true" AllowCustomPaging="true" PageSize="20"
OnRowCommand="gvPresupuestos_RowCommand" 
OnPageIndexChanging="gvPresupuestos_PageIndexChanging" 
DataKeyNames="IdTipoPresupuesto" OnPreRender="gvPresupuestos_PreRender"
ItemType="Core.NominaEntities.TipoPresupuesto"  ShowHeaderWhenEmpty="True" 
UseAccessibleHeader="true" GridLines="None" CssClass="table table-hover">
<Columns>
    <asp:BoundField HeaderText="Nombre del presupuesto" DataField="Nombre"/>
    <asp:TemplateField HeaderText="Opciones">
        <ItemTemplate>
        <asp:LinkButton runat="server" Text="Deshabilitar" 
            Font-Underline="true" CommandName="Deshabilitar" 
            Visible='<%# Item.Editable ? true : false %>'
            CommandArgument='<%# Item.IdTipoPresupuesto %>' />
        <a href='<%# "Detalle?p=" + Item.IdTipoPresupuesto.ToString() %>' 
            target="_self"><%# Item.Editable ? "Editar" : "Ver" %></a>
        </ItemTemplate>
    </asp:TemplateField>
    <asp:ButtonField ButtonType="Link" CommandName="Deshabilitar" 
    Text="Deshabilitar (this fires event)" />
</Columns>
</asp:GridView>

<table class="large-table">
    <tr>
        <td class="text-right">
            <a runat="server" class="btn btn-primary" href="Detalle">Nuevo presupuesto</a>
        </td>
    </tr>
</table>
</asp:Content> 

Code behind

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        InitializeControls();
        SetPermissions();
        FillView(1);
    }
}

protected void gvPresupuestos_PreRender(object sender, EventArgs e)
{
    // Habilita bootstrap
    gvPresupuestos.HeaderRow.TableSection = TableRowSection.TableHeader;
}

protected void gvPresupuestos_RowCommand(object sender, GridViewCommandEventArgs e)
{
    // This is never fired by the LinkButton in the ItemTemplate
    // But the ButtonField actually fires it.
    if (e.CommandName.Equals("Deshabilitar"))
    {
        // This is how I've been doing it in the whole project but thanks to this 
        // shit I can't use the CommandArgument of the LinkButton in the ItemTemplate
        // Guid idPresupuesto = new Guid(e.CommandArgument.ToString());

        // I don't know what I'm supposed to do now. 
        // ¿Why this only happens in this page?, ¿WTF?
        Guid idPresupuesto = gvPresupuestos.GetTheIdFromDataKeysWithFuckingMagic();
        var cliente = ClientFactory.CreateServiceClient();
        using (cliente as IDisposable)
        {
            cliente.DeshabilitarPresupuesto(idPresupuesto);
        }
    }
    FillView(1);
}

protected void gvPresupuestos_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
    gvPresupuestos.PageIndex = e.NewPageIndex;
    FillView(e.NewPageIndex + 1);
}

#region helper methods
private void InitializeControls()
{
    // Not required yet
}

private void FillView(int desiredPage)
{
    var cliente = ClientFactory.CreateAuthServiceClient();
    using (cliente as IDisposable)
    {
        var resultado = cliente.ObtenerTiposDePresupuesto();
        gvPresupuestos.DataSource = resultado;
        gvPresupuestos.DataBind();
    }
}

private void SetPermissions()
{
    // not required yet
}
#endregion

I've tried enabling and disabling viewstate in the gridview but didn't get different results.

Here is what happens with breakpoints:

  1. You type the url and load the page for the first time.
  2. Then you access the code in the block if(!IsPostBack).
  3. Now you can click both the LinkButton in the ItemTemplate and the ButtonField(Look screenshot)
    • If you click the LinkButton in the ItemTemplate, it doesn't fire gvPresupuestos_RowCommand. It does a postback, of course. But gvPresupuestos_RowCommand simply doesn't get fired. My code doens't handle that weird postback and the page does the things it would do with a regular postback. After it, you end up with an empty gridview because in the flow of this postback, FillView() is never called.(Look screenshot)
    • If you click the ButtonField, the event gvPresupuestos_RowCommand is fired, and everything is normal. But I require the IdPresupuesto of the clicked row and I don't know how to get it now.

This is weird. I've implemented this model in all the info pages of the system (there are like 15 modules like this) and never had problems until now.

dave doe
  • 71
  • 1
  • 2
  • 1
    If you have a NEW question, please ask it by clicking the [Ask Question](//stackoverflow.com/questions/ask) button. If you have sufficient reputation, [you may upvote](//stackoverflow.com/privileges/vote-up) the question. Alternatively, "star" it as a favorite and you will be notified of any new answers. – Rohit Gupta Jul 28 '15 at 19:57
  • @RohitGupta, I found the answer, how I should share this info with the community now? Is there a "things-i-know-section" on stackoverflow? – dave doe Jul 28 '15 at 22:04
  • 1
    @davedoe, Just edit the above answer. If its indeed a new question then ask the question in the normal way and then answer it yourself. You are allowed to do this. – Rohit Gupta Jul 28 '15 at 22:36
0

I had the same problem for a LinkButton in a ListView. Turns out I should have been using OnItemCommand in the ListView, not OnRowCommand.

Changing this fixed the issue.

Also, you must have a CommandName set on the LinkButton (but no OnCommand).

Resource
  • 524
  • 4
  • 16