2010-06-09 22 views
5

Trong điều khiển người dùng, tôi có một Repeater bên trong UpdatePanel (id được hiển thị bên trong ModalPopupExtender. Repeater là databound sử dụng danh sách mảng các đối tượng MyDTO. Có hai nút cho Mỗi mục trong danh sách Khi ràng buộc ImageURL và CommandArgument được thiết lậpUpdatePanel, Repeater, DataBinding Problem

Mã này hoạt động tốt vào lần đầu tiên nhưng CommandArgument là sai sau đó. Có vẻ như màn hình được cập nhật chính xác nhưng DTO không phải là và CommandArgument đã gửi là một trong số đó vừa bị xóa.

Ai có thể phát hiện bất kỳ vấn đề nào với mã không?

Chỉnh sửa: Tôi vừa thêm một CollapsiblePanelExtender vào mã. Khi tôi xóa một mục và mở rộng bảng điều khiển, mục đã bị xóa trước đó (và rời khỏi màn hình) đã trở lại. Có vẻ như Repeater đã không được xây dựng lại một cách chính xác dưới nắp ca-pô.

ascx

<asp:UpdatePanel ID="ViewDataDetail" runat="server" ChildrenAsTriggers="true"> 
    <Triggers> 
     <asp:PostBackTrigger ControlID="ViewDataCloseButton" /> 
     <asp:AsyncPostBackTrigger ControlID="DataRepeater" /> 
    </Triggers> 
    <ContentTemplate> 
     <table width="100%" id="DataResults"> 
     <asp:Repeater ID="DataRepeater" runat="server" OnItemCommand="DataRepeater_ItemCommand" OnItemDataBound="DataRepeater_ItemDataBound"> 
     <HeaderTemplate> 
      <tr> 
      <th><b>Name</b></th> 
      <th><b>&nbsp;</b></th> 
      </tr> 
     </HeaderTemplate> 
      <ItemTemplate> 
      <tr> 
       <td> 
       <b><%#((MyDTO)Container.DataItem).Name%></b> 
       </td> 
       <td> 
       <asp:ImageButton CausesValidation="false" ID="DeleteData" CommandName="Delete" runat="server" /> 
       <asp:ImageButton CausesValidation="false" ID="RunData" CommandName="Run" runat="server" /> 
       </td> 
      </tr> 
      <tr> 
       <td colspan="2"> 
       <table> 
        <tr> 
        <td>Description : </td> 
        <td><%#((MyDTO)Container.DataItem).Description%></td> 
        </tr> 
        <tr> 
        <td>Search Text : </td> 
        <td><%#((MyDTO)Container.DataItem).Text%></td> 
        </tr> 
       </table> 
       </td> 
      </tr> 
      </ItemTemplate> 
     </asp:Repeater> 
     </table> 
    </ContentTemplate> 
</asp:UpdatePanel> 

Code-Behind

public DeleteData DeleteDataDelegate; 
    public RetrieveData PopulateDataDelegate; 
    public delegate ArrayList RetrieveData(); 
    public delegate void DeleteData(String sData); 


protected void Page_Load(object sender, EventArgs e) 
    { 
     //load the initial data.. 
     if (!Page.IsPostBack) 
     { 
      if (PopulateDataDelegate != null) 
      { 
       this.DataRepeater.DataSource = this.PopulateDataDelegate(); 
       this.DataRepeater.DataBind(); 
      } 
     } 
    } 

    protected void DataRepeater_ItemCommand(object source, RepeaterCommandEventArgs e) 
    { 
     if (e.CommandName == "Delete") 
     { 
      if (DeleteDataDelegate != null) 
      { 
       DeleteDataDelegate((String)e.CommandArgument); 
       BindDataToRepeater(); 
      } 
     } 
     else if (e.CommandName == "Run") 
     { 
      String sRunning = (String)e.CommandArgument; 
      this.ViewDataModalPopupExtender.Hide(); 
     } 
    } 

    protected void DataRepeater_ItemDataBound(object source, RepeaterItemEventArgs e) 
    { 
     RepeaterItem item = e.Item; 
     if (item != null && item.DataItem != null) 
     { 
      MyDTO oQuery = (MyDTO)item.DataItem; 

      ImageButton oDeleteControl = (ImageButton) item.FindControl("DeleteData"); 
      ImageButton oRunControl = (ImageButton)item.FindControl("RunData"); 

      if (oDeleteControl != null && oRunControl !=null) 
      { 
       oRunControl.ImageUrl = "button_expand.gif"; 
       oRunControl.CommandArgument = "MyID"; 
       if (oQuery !=null) 
       { 
        //do something 
       } 
       oDeleteControl.ImageUrl = "btn_remove.gif"; 
       oDeleteControl.CommandArgument = "MyID"; 
      } 
     } 
    } 

    public void BindDataToRepeater() 
    { 
     this.DataRepeater.DataSource = this.PopulateDataDelegate(); 
     this.DataRepeater.DataBind(); 
    } 

    public void ShowModal(object sender, EventArgs e) 
    { 
     BindDataToRepeater(); 
     this.ViewDataModalPopupExtender.Show(); 
    } 
+0

Có mã nào bị thiếu trong trình xử lý 'ItemDataBound' của bạn không? Bên trong phương thức đó, bạn khai báo một biến 'MyDTO' (' oQuery') sau đó không bao giờ sử dụng nó. –

+0

xin lỗi, vâng, tôi đã cắt nó xuống một cách ngắn gọn –

Trả lời

7

Cảm ơn bạn đã nhắc tôi tại sao tôi ngừng sử dụng các điều khiển ASP.NET. Đây là loại cơn ác mộng chính xác đã khiến quá nhiều dự án đi qua ngân sách và lịch biểu.

Lời khuyên của tôi cho bạn là suy nghĩ về cách đơn giản nhất để thực hiện việc này. Bạn có thể cố gắng uốn cong về phía sau để có được điều này để làm việc theo cách ASP.NET hoặc đi theo con đường ngắn nhất. Tất cả những gì bạn đang làm là tạo HTML, không bao giờ khó khăn như vậy.

Nguyên nhân rất có thể gây ra sự cố của bạn là ViewState được lưu trữ trong trang không được cập nhật trên một phần đăng lại. Vì vậy, với mọi thay đổi trong bảng cập nhật, bạn sẽ đăng lại chế độ xem ban đầu của trang.

Hãy thử thay thế bộ lặp bằng một vòng lặp đơn giản (và bỏ qua những người bắt đầu phàn nàn bạn không nên trộn đánh dấu và mã). Thay thế các câu lệnh dữ liệu của bạn bằng <%= %>. Điều đó giúp loại bỏ trạng thái xem tất cả cùng nhau và nên xóa mọi hàng bị xóa khỏi xuất hiện lại.

+0

bạn hoàn toàn đúng, tôi đã ngừng làm phiền với những thứ này và mọi thứ đều là jQuery với các dịch vụ web. Cuộc sống của tôi dễ dàng hơn 100% và mọi thứ nhanh hơn rất nhiều để thực hiện .. –

1

Sau nhiều ngày làm rối tung xung quanh với điều này tôi đã không tìm thấy một sửa chữa thích hợp cho vấn đề nhưng có một khả thi công việc xung quanh .

CollapsiblePanelExtender được đặt thành NOT tự động đăng lại để khắc phục sự cố dữ liệu đã xóa xuất hiện lại khi mở rộng bộ mở rộng. Một vấn đề khác, tôi tin là có liên quan.

Dường như ViewState cho Repeater không đồng bộ với dữ liệu. e.CommandArgument không phải lúc nào cũng đúng và dường như tham khảo dữ liệu trước đó. Tôi đã cố gắng sửa chữa nó bằng cách lưu trữ ArrayList của các đối tượng MyDTO trong ViewState khi mở hộp thoại Modal và sử dụng ID được lấy từ e.Item.ItemIndex để tìm phần tử chính xác cần xóa. Điều này không hoạt động chính xác, ArrayList đã rút khỏi ViewState không đồng bộ.

Lưu trữ ArrayList trong phiên làm cho tất cả hoạt động khiến tôi tin rằng tôi đang làm điều gì đó sai về cơ bản hoặc có lỗi nhỏ trong phiên bản bộ công cụ mà tôi đang sử dụng (chúng tôi vẫn tiếp tục VS2005 bị mắc kẹt với phiên bản cũ của bộ công cụ)

Xin lỗi nếu điều này không có ý nghĩa, hãy liên hệ với tôi nếu bạn muốn làm rõ mọi thứ.

1

thử sử dụng

((IDataItemContainer) container) .DataItem

thay vì "Container.DataItem"

Nó làm việc cho tôi.