Question

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);
  }
Was it helpful?

Solution

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.

OTHER TIPS

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

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top