2009-11-23 35 views
8

Đây là một vấn đề phổ biến vô lý và đã cạn kiệt tất cả các giải pháp rõ ràng, tôi hy vọng SO có thể cung cấp cho tôi một số đầu vào ... Tôi có một UserControl bên trong một trang chứa một bộ lặp có một số điều khiển gây ra postback. Rắc rối là, tất cả các điều khiển bên trong của bộ lặp không bao giờ nhấn xử lý sự kiện của họ khi họ postback, nhưng điều khiển bên ngoài của repeater (vẫn còn trong UC) được xử lý một cách chính xác. Tôi đã đảm bảo rằng các điều khiển của tôi không được tái tạo do thiếu if(!IsPostBack) và tôi đã xác minh rằng Request.Form ["__ EVENTTARGET"] chứa ID kiểm soát chính xác trong sự kiện Page_Load. Tôi đã cố gắng tái tạo các triệu chứng trong một dự án riêng biệt và nó đã hoạt động như mong muốn.ASP.NET - Kiểm soát sự kiện không kích hoạt bên trong Repeater

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

Mã này được cố tình thiếu chức năng vì vậy chỉ cần bỏ qua thực tế là.

Trả lời

2

Tôi đã tìm thấy thẻ td bị thiếu trong Itemtemplate, đôi khi DOM không chính xác, thì updatapanel làm những điều kỳ lạ.

+0

Bắt tốt, nhưng bạn thực sự có thể bỏ qua điều đó. Đánh dấu tôi đang hiển thị thậm chí không giống như mã sản xuất. Tôi tạo ra chỉ để hiển thị hiệu ứng. Tất cả các điều khiển bên trong ItemTemplate đều hoạt động theo cùng một cách. –

3

Mã đã chỉnh sửa của bạn có các thuộc tính còn lại CommandArgumentCommandName; bạn có thực sự xử lý sự kiện Repeater.ItemCommand không?

Nếu có, và nếu trang của bạn gọi phương thức Fill của điều khiển trên đăng lại, điều đó sẽ giải thích được.

tóc rách vấn đề ASP.NET cổ điển này được giải thích trong các bài viết: A Stumper of an ASP.NET QuestionA Stumper of an ASP.NET Question: SOLVED!

Lời giải thích là một chút tâm-uốn, nhưng mấu chốt của nó là Repeater.DataBind cản trở khả năng ASP.NET để xác định nút lặp nào gây ra một postback.

+0

Mặc dù tôi đang sử dụng các đối số CommandArgument và CommandName nhưng tôi không sủi bọt các sự kiện thông qua Repeater.ItemCommand. Tôi đang sử dụng các thuộc tính để lưu trữ thông tin mà tôi truy cập trong sự kiện nhấp nút chuẩn. –

+0

tôi nghĩ rằng liên kết nên là http://scottonwriting.net/sowBlog/archive/0000/00/00/162929.aspx – darasd

+0

@darasd - cảm ơn bạn đã sửa liên kết! –

2

Chỉ khoảng EVERY thời gian tôi gặp phải vấn đề này bởi vì DataBind() đang được gọi khi nó không được. Điều này sẽ giết hầu hết các sự kiện từ các điều khiển bên trong một bộ lặp. Tôi thấy bạn có một IsPostBack kiểm tra trong Page_Load của bạn ... vì vậy đó là một sự khởi đầu. Nhưng hãy thử đặt một breakpoint trên repNotes.DataBind() và xem nó có được gọi khi bạn không mong đợi nó.

Tính năng này có hoạt động OK bên ngoài UpdatePanel không?

+0

DataBind() chỉ được gọi trên tải trang ban đầu và sau khi các sự kiện điều khiển được chỉ định - không có sự kiện nào đang được kích hoạt như chúng cần. UpdatePanel dường như không liên quan đến vấn đề. Tôi có một hình thức trong ứng dụng của tôi mà cũng được sử dụng để làm việc đó là trưng bày hành vi tương tự như là tốt, khi các hình thức gửi lại repeater trống chính nó như nó không ở đây. Hành vi rất lạ. –

+0

Bạn chưa tắt ViewState cho bất kỳ điều khiển nào trong số những điều khiển này? Bạn có "một hình thức khác" ... Tôi cho rằng đó là một trang .aspx khác nhau hoàn toàn? Bạn không có thẻ biểu mẫu bổ sung trong trang này? – Bryan

+0

Nhận xét của Bryan đã giúp tôi: trong trường hợp của tôi, tôi đã có EnableViewState = "false" trên bộ lặp gốc và điều đó ngăn cản trình xử lý postback của chân trang bị sa thải. – fortboise

0

Tôi đã gặp phải sự cố tương tự. Nó xảy ra với tôi nếu tôi chạy DataBind hai lần. Nói cách khác khi tôi cư trú kiểm soát lặp lại hai lần (vì lý do nào) các sự kiện sẽ không cháy.

Tôi hy vọng điều đó sẽ hữu ích.

0

Tôi cũng gặp sự cố này. Làm tôi phát điên vì tôi không hồi phục lại bộ lặp của mình, tôi đã cố gắng thêm một trình xử lý sự kiện, thay đổi cài đặt khung nhìn tất cả mọi nơi, không có gì hiệu quả.

Câu trả lời trong trường hợp của tôi là tôi đã gọi "Page.DataBind()" trong Trang chính, để xử lý một số biến số mã hóa đã bị ràng buộc với trang bằng cách sử dụng cú pháp <% # MyVar%>.

Một khi tôi đã lấy Page.DataBind() nó đã hoạt động, tôi chỉ phải recode Master Page để kéo dữ liệu đó theo một cách khác. Vì vậy, tôi đoán nếu bạn đang làm một DataBind() bất cứ nơi nào lên chuỗi cho trang của bạn, điều khiển người dùng, lớp cơ sở trang, trang chủ, vv nó có thể giết chết của bạn ViewState và sự kiện bubbling.

Các vấn đề liên quan