2009-11-23 16 views
8

Dies ist ein absurd häufiges Problem und alle die offensichtlichen Lösungen erschöpft, ich hoffe, dass SO mir einige Eingaben bieten kann ... Ich habe ein UserControl innerhalb einer Seite, die enthält ein Repeater mit mehreren Steuerelementen, die Postback verursachen. Das Problem ist, dass alle Steuerelemente innerhalb des Repeaters ihre Ereignisbehandlungsroutinen beim Postback nie berühren, aber die Steuerungen außerhalb des Repeaters (immer noch im UC) werden korrekt behandelt. Ich habe bereits sichergestellt, dass meine Steuerelemente aufgrund einer fehlenden if(!IsPostBack) nicht generiert wurden, und ich habe überprüft, dass Request.Form ["__ EVENTTARGET"] die richtige Steuerelement-ID in dem Ereignis Page Load enthielt. Ich habe versucht, die Symptome in einem separaten Projekt zu reproduzieren, und es funktionierte wie es sollte.ASP.NET - Control Events nicht innerhalb Repeater Firing

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

Der Code absichtlich Funktionalität fehlt so außer Acht lassen nur diese Tatsache.

Antwort

2

Ich habe ein fehlendes td-Tag in Itemtemplate gefunden, manchmal, wenn DOM nicht korrekt ist, macht das updatapanel seltsame Dinge.

+0

Guter Fang, aber Sie können das tatsächlich ignorieren. Das Markup, das ich zeige, ist nicht dasselbe wie der Produktionscode. Ich habe das nur erstellt, um den Effekt zu zeigen. Alle Steuerelemente in ItemTemplate verhalten sich auf die gleiche Weise. –

3

Ihr bearbeiteter Code weist die Eigenschaften CommandArgument und CommandName auf; Behandelst du tatsächlich das Repeater.ItemCommand Ereignis?

Wenn ja, und wenn Ihre Seite die Methode Fill des Steuerelements auf Postbacks aufruft, würde das erklären.

Dieses klassischen ASP.NET Haar Zerreißen Problem wird in diesem Posten erklärt: A Stumper of an ASP.NET Question und A Stumper of an ASP.NET Question: SOLVED!

Die Erklärung etwas kniffligen, aber der Kernpunkt ist, dass Repeater.DataBind mit ASP.NET Fähigkeit beeinträchtigt zu Bestimmen Sie, welcher Repeater-Button ein Postback verursacht hat.

+0

Obwohl ich die CommandArgument- und CommandName-Argumente verwende, sprude ich keine Ereignisse durch Repeater.ItemCommand. Ich verwende die Eigenschaften, um Informationen zu speichern, auf die ich im Click-Ereignis der Standardschaltfläche zugreifen kann. –

+0

Ich denke, der Link sollte sein http://scottonwriting.net/sowBlog/archive/0000/00/00/162929.aspx – darasd

+0

@darasd - danke für die Linkkorrektur! –

2

JEDES Mal, wenn ich auf dieses Problem stoße, ist es, weil DataBind() aufgerufen wird, wenn es nicht sein sollte. Dadurch werden die meisten Ereignisse von Steuerelementen in einem Repeater beendet. Ich sehe, Sie haben ein! IsPostBack überprüfen Sie Ihre Page_Load ... also das ist ein Anfang. Versuchen Sie jedoch, einen Haltepunkt auf repNotes.DataBind() zu setzen, und sehen Sie, ob es aufgerufen wird, wenn Sie es nicht erwarten.

Funktioniert es OK außerhalb eines UpdatePanel?

+0

DataBind() wird nur beim ersten Laden der Seite und nach den angegebenen Steuerungsereignissen aufgerufen, von denen keines so ausgelöst wird, wie sie sollten. Das UpdatePanel scheint nicht auf das Problem bezogen zu sein. Ich habe ein anderes Formular in meiner App, das auch funktioniert, das auch ein ähnliches Verhalten zeigt, wenn das Formular zurückbucht, leert sich der Repeater selbst wie hier. Sehr seltsames Verhalten. –

+0

Sie haben ViewState nicht für eines dieser Steuerelemente deaktiviert? Sie haben "eine andere Form" ... Ich nehme an, das ist eine andere ASPX-Seite insgesamt? Sie haben kein zusätzliches Formular-Tag auf dieser Seite? – Bryan

+0

Bryan's Kommentar half mir: In meinem Fall hatte ich EnableViewState = "false" auf dem Eltern-Repeater, und das verhinderte, dass der Postback-Handler des Footer Controls ausgelöst wurde. – fortboise

0

Ich lief auf das gleiche Problem. Es ist mir passiert, wenn ich den DataBind zweimal ausgeführt habe. Mit anderen Worten, wenn ich das Repeater-Steuerelement zweimal (aus irgendeinem Grund) besetze, werden die Ereignisse nicht ausgelöst.

Ich hoffe, dass hilft.

0

Ich lief auch in dieses Problem. Hat mich verrückt gemacht, weil ich meinen Repeater nicht wieder anbindete, ich habe versucht, dynamisch einen Event-Handler hinzuzufügen, die ViewState-Einstellungen überall zu ändern, nichts hat funktioniert. Die Antwort in meinem Fall war, dass ich "Page.DataBind()" in der Masterseite aufruft, um einige Codebehind-Variablen zu behandeln, die mit der <% # MyVar%> -Syntax an die Seite gebunden wurden.

Sobald ich die PageDataBind() nahm es funktionierte, musste ich nur die Master-Seite neu codieren, um diese Daten auf andere Weise einzuziehen.

Also ich denke, wenn Sie ein DataBind() irgendwo entlang der Kette für Ihre Seite, Benutzerkontrolle, Seitenbasisklasse, Masterseite, etc. tun, könnte es Ihre Viewstate und Event Bubbling töten.

Verwandte Themen