3

Why would a button inside a Repeater not fire the Repeater's ItemCommand event? Is there a way to force it to do so? ViewState is Enabled.

In the code below, btnApprove and btnDelete are the buttons in question:

<asp:Repeater runat="server" ID="rpt1" onitemdatabound="rpt1_ItemDataBound" onitemcommand="rpt1_ItemCommand" >
    <ItemTemplate>
        <table width="100%" style="margin-bottom:6px;">
            <tr>
                <td>
                    <asp:CheckBox ID="chkSelected" runat="server" Text=" " TextAlign="Right"/> Select
                    <asp:Button ID="btnApprove" runat="server" Width="80px" Text="Approve" />
                    <asp:Button ID="btnDelete" runat="server" Width="80px" Text="Delete" />
                </td>                                                                   
            </tr>
            <tr>
                <td align="right">
                    <asp:Label ID="lblCommentStatus" runat="server" Text="Label"></asp:Label>
                </td>
            </tr>
        </table>
        <table width="100%" style="margin-top:6px;">
            <tr>
                <td><asp:Label ID="lblAuthorName" runat="server" Text="Author: " Width="60px"></asp:Label></td>
                <td><asp:TextBox ID="txtAuthorName" runat="server" Width="250px"></asp:TextBox></td>
                <td style="padding-left: 30px;"><asp:Label ID="lblAuthorLocation" runat="server" Text="Location: " Width="70px"></asp:Label></td>
                <td><asp:TextBox ID="txtAuthorLocation" runat="server" Width="250px"></asp:TextBox></td>
            </tr>
        </table>
        Title: <asp:TextBox ID="txtTitle" runat="server" Width="640px" Enabled="False"></asp:TextBox>
        Body: <asp:TextBox ID="txtBody" runat="server" Width="640px" TextMode="MultiLine" Height="60px" Enabled="False"></asp:TextBox>
        <table width="100%" style="margin-top:6px;">
            <tr>
                <td><asp:Label ID="lblVotes" runat="server" Text="Votes: " Width="80px"></asp:Label></td>
                <td><asp:Label ID="lblVotesCount" runat="server" Text="" Width="600px"></asp:Label></td>
            </tr>
        </table>
        <hr style="margin-top:20px; margin-bottom:20px;" />
    </ItemTemplate>
</asp:Repeater>

/// <summary>
  /// Handles the ItemCommand event of the rpt1 control.
  /// </summary>
  /// <param name="source">The source of the event.</param>
  /// <param name="e">The <see cref="System.Web.UI.WebControls.RepeaterCommandEventArgs"/> instance containing the event data.</param>
  protected void rpt1_ItemCommand(object source, RepeaterCommandEventArgs e)
  {
    var c1 = CommentRepository.GetById(Convert.ToUInt64(e.CommandArgument.ToString()));

    if (e.CommandName == "approve")
    {
      c1.Approved = true;
      c1.ApprovationUserId = WebAdminContext.RelatedUserId;
    }

    if (e.CommandName == "reject")
    {
      c1.Approved = false;
      c1.ApprovationUserId = 0;
    }

    if (e.CommandName == "delete")
    {
      c1.Deleted = true;
      c1.DeletionUserId = WebAdminContext.RelatedUserId;
    }

    if (e.CommandName == "restore")
    {
      c1.Deleted = false;
      c1.DeletionUserId = 0;
    }

    CommentRepository.Update(c1);

    ResetSubSequenceInfo();
    BindList();
      }

/// <summary>
  /// Binds the list.
  /// </summary>
  private void BindList()
  {
    _Criteria = lcb1.GenerateCriteriaFromUI();

    var sc1 = CommentRepository.Filter(
      new FilteringOptions(
        EntityListPager1.CurrentSubSequenceInfo,
        null,
        CommentRepository.GetCriteriaToFilterByTGID(CurrentEntityGEODEReference.GID).And(_Criteria)
        )
      );

    // BIND
    rpt1.DataSource = sc1.Items;
    rpt1.DataBind();

    EntityListPager1.BindToUI(sc1.Info);
  }
Mark Richman
  • 28,948
  • 25
  • 99
  • 159
  • Maybe it's soon time to accept an answer, if one of them solved the problem. I assume it was the rebind-every-time problem? – Niels Brinch Aug 30 '12 at 13:30

3 Answers3

15

Edit: per your other comments, it sounds like you're re-binding the repeater on every postback. When you do that, you destroy the ItemCommand's event source - the original Repeater item associated with the button the client clicked.

The user selects "approved" or "deleted" from a dropdown, clicks search (a postback) and BindList() binds the datasource the to new results.

You can re-bind the repeater in your drop-down's handler, just make sure you aren't doing it during the execution path initiated by your 'Approve' or 'Delete' buttons.


There may be another issue, but you definitely need to specify command names for your buttons for that code to work:

<asp:Button ID="btnApprove" runat="server" Width="80px" Text="Approve" CommandName="approve"/>
<asp:Button ID="btnDelete" runat="server" Width="80px" Text="Delete" CommandName="delete"/>

I can't reproduce the problem: are you sure the ItemCommand handler isn't even firing? Using a slightly modified version of your code, my rpt1_ItemCommand method is clearly executing when I click 'Approve' or 'Delete', it just isn't hitting any of the cases, because those buttons don't have command names defined.

Jeff Sternal
  • 47,787
  • 8
  • 93
  • 120
  • The event does not fire at all. I've got a breakpoint right at the top of the event handler. All other page events fire just fine. Setting CommandName on the two buttons has no effect. – Mark Richman Mar 26 '10 at 15:55
  • 1
    Somehow I don't think the button's click event is bubbling up to the repeater. I overrided OnBubbleEvent and the button event is not trapped. – Mark Richman Mar 26 '10 at 15:57
9

When do you bind your repeater? If you do it manually, be sure that you only bind it, if the page is not a postback.

Provide some more code please

citronas
  • 19,035
  • 27
  • 96
  • 164
  • I have to bind the list on postback, because the list is bound to results whose criteria vary based on a dropdownlist on the page. The user selects "approved" or "deleted" from a dropdown, clicks search (a postback) and BindList() binds the datasource the to new results. – Mark Richman Mar 26 '10 at 15:53
  • 1
    @Mark - do you mean you're re-binding the repeater even on these "Approve" and "Delete" button clicks? Do you have `EnableEventValidation` set to `false` in the page directive? If so, this is the source of the problem. (I can explain more in my answer if this is correct.) – Jeff Sternal Mar 26 '10 at 15:59
  • 2
    You can't rebind the list on every postback. This will make your RowCommand event force to be lost. Rebind only on !Page.IsPostback and in eventhandler that are called after OnRowCommand has already been processed – citronas Mar 26 '10 at 16:03
  • @Mark Richman: I believe the outstanding question is: when does the repeater get bound for the first time? And is this protected with a if (!IsPostBack) check? – NotMe Mar 26 '10 at 16:28
  • This was my problem. Thanks so much. – Robin Winslow Jan 30 '13 at 08:51
1

As the other 2 posts describe

  • Do not rebind on PostBack
  • Make sure you set the CommandName property on the Button

And another problem i had, was having EnableViewState property on the Repeater set to false, it needs to be set to true.

Neil
  • 1,912
  • 17
  • 24