这是一个荒谬的常见问题,已经耗尽了所有明显的解决方案,我希望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;
}
}
代码故意遗漏功能,所以请忽略这一事实。
答案 0 :(得分:3)
您修改后的代码具有剩余的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确定哪个转发器按钮导致回发的能力。
答案 1 :(得分:2)
我在Itemtemplate中发现了一个丢失的td-tag,有时当DOM不正确时,updatapanel会做一些奇怪的事情。
答案 2 :(得分:2)
几乎每次我遇到这个问题都是因为DataBind()在不应该被调用时被调用。这将从转发器内的控件中杀死大多数事件。我看到你有一个!IsPostBack检查你的Page_Load ...所以这是一个开始。但是尝试在repNotes.DataBind()上设置一个断点,看看它是否在你不期望它时被调用。
在UpdatePanel之外它是否正常工作?
答案 3 :(得分:0)
我遇到了同样的问题。如果我两次运行DataBind,就会发生这种情况。换句话说,当我填充转发器控件两次(由于任何原因)时,事件不会触发。
我希望有所帮助。
答案 4 :(得分:0)
我也遇到了这个问题。驱使我疯狂,因为我没有重新绑定我的转发器,我尝试动态添加一个事件处理程序,改变整个地方的视图状态设置,没有任何效果。
我的答案就是我在Master Page中调用了“Page.DataBind()”来处理一些使用&lt;%#MyVar%&gt;绑定到页面的代码隐藏变量。语法。
一旦我取出了Page.DataBind(),我就不得不重新编写母版页,以不同的方式提取数据。
所以我猜你是否在你的页面,用户控件,页面基类,母版页等链的任何地方做了DataBind(),它可能会杀死你的viewstate和事件冒泡。