views:

980

answers:

2

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);
  }
+3  A: 

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
thanks - i updated the post with a code sample
Mark Richman
Add more code. When is BindList() called? In Page_Load?
citronas
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
@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
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
@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?
Chris Lively
+3  A: 

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
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
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