这是一个荒谬的常见问题,已经耗尽了所有明显的解决方案,我希望SO能为我提供一些输入……我在一个页面内有一个UserControl,其中包含一个转发器,它包含几个导致回发的控件.麻烦的是,转发器内部的所有控件在回发时都不会碰到它们的事件处理程序,但是转发器外部的控件(仍在UC中)可以正确处理.我已经确定我的控件没有被重新生成,因为缺少if(!IsPostBack)并且我验证了Request.Form [“__ EVENTTARGET”]在Page_Load事件中包含正确的控件ID.我试图在一个单独的项目中重现这些症状,并且它可以正常工作.
<%@ 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; } }
解决方法
您编辑的代码具有残余的CommandArgument和CommandName属性;你实际上是在处理Repeater.ItemCommand事件吗?
如果是这样,如果你的页面在回发上调用控件的Fill方法,那就可以解释它.
这些经典的ASP.NET头发撕裂问题在这些帖子中有解释:A Stumper of an ASP.NET Question和A Stumper of an ASP.NET Question: SOLVED!
解释有点令人费解,但其关键在于Repeater.DataBind干扰了ASP.NET确定哪个转发器按钮导致回发的能力.