2009-11-23 31 views
8

这是一个荒谬的常见问题,并已耗尽所有明显的解决方案,我希望可以为我提供一些输入...我有一个UserControl内页面,其中包含一个中继器包含几个可引起回传的控制。问题在于,中继器内部的所有控件在回发时都不会触发它们的事件处理程序,但在中继器外部(仍在UC中)的控件可以正确处理。我已经确定我的控件由于缺少if(!IsPostBack)而没有被重新生成,并且我确认Request.Form [“__ EVENTTARGET”]在Page_Load事件中包含正确的控件ID。我试图在一个单独的项目中重现这些症状,并且它的工作原理应该如此。ASP.NET - 控制事件不直接触发直放站

<%@ 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; 
    } 
} 

的代码是故意所缺少的功能所以只是无视这一事实。

回答

2

我在Itemtemplate中发现缺少td-tag,有时候DOM不正确时,updatapanel会做一些奇怪的事情。

+0

好,但你实际上可以忽略这一点。我所显示的标记与生产代码不一样。我创建了来显示效果。 ItemTemplate内的所有控件的行为方式都是相同的。 – 2009-11-23 20:43:47

3

您的编辑代码有残留CommandArgumentCommandName属性;你真的在处理Repeater.ItemCommand事件吗?

如果是这样,并且您的页面在回发中调用控件的Fill方法,那就可以解释它。

这款经典的ASP.NET头发撕裂问题是,在这些职位解释说:A Stumper of an ASP.NET QuestionA Stumper of an ASP.NET Question: SOLVED!

的解释是有点令人费解,但问题的症结所在是Repeater.DataBind与ASP.NET的能力,干扰确定哪个中继器按钮导致回发。

+0

虽然我使用CommandArgument和CommandName参数,但我不是通过Repeater.ItemCommand冒泡事件。我正在使用这些属性来存储我在标准按钮单击事件中访问的信息。 – 2009-11-23 22:15:47

+0

我认为链接应该是http://scottonwriting.net/sowBlog/archive/0000/00/00/162929.aspx – darasd 2010-06-15 09:59:09

+0

@darasd - 感谢您的链接更正! – 2010-06-15 11:13:28

2

几乎每次我碰到这个问题,这是因为DataBind()不应该被调用。这将杀死中继器内的大多数事件。我看到你有一个!IsPostBack检查你的Page_Load ...所以这是一个开始。但是尝试在repNotes.DataBind()上放置一个断点并查看它是否在你不期望的时候被调用。

在UpdatePanel之外它可以正常工作吗?

+0

DataBind()仅在初始页面加载和指定的控件事件之后被调用 - 它们都不应该被触发。 UpdatePanel似乎没有涉及到这个问题。当我的应用程序中还有另一种表单,它也用于表现类似行为的工作,当表单回传中继器时会自动清空它。非常奇怪的行为。 – 2009-11-24 16:18:16

+0

你有没有禁用ViewState的任何这些控制你?你有“另一种形式”...我认为这是一个完全不同的.aspx页面?你在这个页面没有额外的表格标签? – Bryan 2009-11-24 20:27:21

+0

Bryan的评论帮助了我:在我的情况下,我在父节点上使用了EnableViewState =“false”,并且阻止了脚注控件的回发处理程序被触发。 – fortboise 2011-10-18 16:22:32

0

我遇到了同样的问题。它发生在我身上,如果我已经运行了两次DataBind。换句话说,当我将中继器控件填充两次(出于任何原因)事件不会触发。

我希望有帮助。

0

我也遇到了这个问题。驱使我疯狂,因为我没有重组我的中继器,我试着动态地添加一个事件处理程序,改变视图状态设置遍布整个地方,没有任何工作。

我的答案是,我在母版页中调用“Page.DataBind()”来处理一些使用<%#MyVar%>语法绑定到页面的代码隐藏变量。

一旦我拿出了Page.DataBind()它的工作,我只需要重新编码母版页,以不同的方式拉入这些数据。

所以,我猜如果你正在为你的页面,用户控件,页面基类,母版页等链接上的DataBind(),它可能会导致视图状态和事件冒泡。