English 中文(简体)
ASP.NET - Control Events Not Firing Inside Repeater
原标题:

This is a absurdly common issue and having exhausted all of the obvious solutions, I m hoping SO can offer me some input... I have a UserControl inside a page which contains a repeater housing several controls that cause postback. Trouble is, all of the controls inside of the repeater never hit their event handlers when they postback, but controls outside of the repeater (still in the UC) are correctly handled. I already made sure my controls weren t being regenerated due to a missing if(!IsPostBack) and I verified that Request.Form["__EVENTTARGET"] contained the correct control ID in the Page_Load event. I attempted to reproduce the symptoms in a separate project and it worked as it should.

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="NoteListControl.ascx.cs"
    Inherits="SantekGBS.Web.UserControls.NoteListControl" %>

<asp:UpdatePanel ID="upNotes" runat="server" UpdateMode="Conditional">
    <ContentTemplate>
        <div class="NoteList" id="divNoteList" runat="server">
            <asp:Repeater ID="repNotes" runat="server">
                <HeaderTemplate>
                    <table width="98%" cellpadding="3" cellspacing="0">
                </HeaderTemplate>
                <ItemTemplate>
                    <tr class="repeaterItemRow">
                        <asp:ImageButton ID="ImageButton1" runat="server" ImageUrl="~/Content/images/DeleteIcon.gif"
                            OnClick="ibRemove_Click" CommandArgument= <%# Container.ItemIndex %>  CommandName= <%# Eval("ID") %> 
                            CausesValidation="false" AlternateText="Delete" />
                        <%# Eval("Text") %></td>
                    </tr>
                </ItemTemplate>
                <FooterTemplate>
                    </table>
                </FooterTemplate>
            </asp:Repeater>
            <asp:PlaceHolder ID="phNoNotes" runat="server" Visible="false">
                <div class="statusMesssage">
                    No notes to display.
                </div>
            </asp:PlaceHolder>
        </div>
    </ContentTemplate>
</asp:UpdatePanel>

public partial class NoteListControl : UserControl
{
    [Ninject.Inject]
    public IUserManager UserManager { get; set; }

    protected List<Note> Notes
    {
        get
        {
            if (ViewState["NoteList"] != null)
                return (List<Note>)ViewState["NoteList"];
            return null;
        }
        set { ViewState["NoteList"] = value; }
    }

    public event EventHandler<NoteEventArgs> NoteAdded;
    public event EventHandler<NoteEventArgs> NoteDeleted;
    public event EventHandler<NoteEventArgs> NoteChanged;

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            UtilityManager.FillPriorityListControl(ddlPriority, false);
        }
    }

    protected void ibRemove_Click(object sender, ImageClickEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine("ibRemove POSTBACK"); // This is NEVER hit
    }

    public void Fill(List<Note> notes)
    {
        Notes = notes;
        RefreshRepeater();
    }

    private void RefreshRepeater()
    {
        if (Notes != null && Notes.Any())
        {
            var sorted = Notes.OrderByDescending(n => n.Timestamp);
            Notes = new List<Note>();
            Notes.AddRange(sorted);
            repNotes.Visible = true;
            phNoNotes.Visible = false;
            repNotes.DataSource = Notes;
            repNotes.DataBind();
        }
        else
        {
            repNotes.Visible = false;
            phNoNotes.Visible = true;
        }
    }
}

public class NoteEventArgs : EventArgs
{
    public Note Note { get; set; }
    public NoteEventArgs()
    { }
    public NoteEventArgs(Note note)
    {
        this.Note = note;
    }
}

The code is intentionally missing functionality so just disregard that fact.

问题回答

Your edited code has residual CommandArgument and CommandName properties; are you actually handling the Repeater.ItemCommand event?

If so, and if your page calls the control s Fill method on postbacks, that would explain it.

This classic ASP.NET hair-tearing problem is explained in these posts: A Stumper of an ASP.NET Question and A Stumper of an ASP.NET Question: SOLVED!

The explanation is a little mind-bending, but the crux of it is that Repeater.DataBind interferes with ASP.NET s ability to determine which repeater button caused a postback.

I found a missing td-tag in the Itemtemplate, sometimes when DOM is incorrect, the updatapanel do strange things.

Just about EVERY time I run into this problem it s because DataBind() is being called when it shouldn t be. This will kill most events from controls inside a repeater. I see you have an !IsPostBack check in your Page_Load... so that s a start. But try putting a breakpoint on repNotes.DataBind() and see if it s getting called when you don t expect it.

Does it work OK outside of an UpdatePanel?

I ran into the same problem. It happened with me if I ve ran the DataBind twice. In other words when I populate the repeater control twice (for any reason) the events wont fire.

I hope that helps.





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

How to Add script codes before the </body> tag ASP.NET

Heres the problem, In Masterpage, the google analytics code were pasted before the end of body tag. In ASPX page, I need to generate a script (google addItem tracker) using codebehind ClientScript ...

Transaction handling with TransactionScope

I am implementing Transaction using TransactionScope with the help this MSDN article http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope.aspx I just want to confirm that is ...

System.Web.Mvc.Controller Initialize

i have the following base controller... public class BaseController : Controller { protected override void Initialize(System.Web.Routing.RequestContext requestContext) { if (...

Microsoft.Contracts namespace

For what it is necessary Microsoft.Contracts namespace in asp.net? I mean, in what cases I could write using Microsoft.Contracts;?

Separator line in ASP.NET

I d like to add a simple separator line in an aspx web form. Does anyone know how? It sounds easy enough, but still I can t manage to find how to do it.. 10x!

热门标签