2010-06-09 15 views
5

En un control de usuario, tengo un repetidor dentro de un UpdatePanel (ID que se muestra dentro de un ModalPopupExtender. El repetidor está enlazado mediante una lista de objetos MyDTO. Hay dos botones para cada elemento en la lista. Al vincular, se establecen ImageURL y CommandArgument.UpdatePanel, Repeater, DataBinding Problema

Este código funciona bien la primera vez, pero el CommandArgument es incorrecto a continuación. Parece que la pantalla se actualiza correctamente, pero el DTO no está y el CommandArgument enviado es el que acaba de eliminarse

¿Alguien puede detectar algún problema con el código?

Editar: Acabo de agregar un CollapsiblePanelExtender al código. Cuando elimino un elemento y expandí el panel, el elemento que se eliminó previamente (y desapareció de la pantalla) ha regresado. Parece que el repetidor no se ha reconstruido correctamente debajo del capó.

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> 

de código subyacente

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

¿Falta el código de su controlador 'ItemDataBound'? Dentro de ese método, declaras una variable 'MyDTO' (' oQuery') y nunca la utilizas. –

+0

lo siento, sí, lo recorté para abreviar –

Respuesta

7

Gracias por recordarme por qué dejé de usar controles ASP.NET. Este es el tipo exacto de pesadilla que ha hecho que muchos proyectos superen el presupuesto y el cronograma.

Mi consejo es que piense en la forma más sencilla de implementar esto. Puede tratar de hacer todo lo posible para que esto funcione de la manera ASP.NET o tome la ruta más corta. Todo lo que estás haciendo es generar HTML, nunca debería ser tan difícil.

La causa más probable de su problema es que ViewState se almacena en la página que no se actualiza en una devolución de datos parcial. Por lo tanto, con cada cambio en el panel de actualización devolverá la vista inicial de la página.

Intente reemplazar el repetidor con un simple for-loop (e ignore a las personas que comienzan a quejarse de que no debe mezclar marcado y código). Reemplace sus declaraciones de enlace de datos con <%= %>. Eso elimina el estado de vista todos juntos y debe eliminar cualquier fila eliminada de volver a aparecer.

+0

tienes toda la razón, he dejado de molestarme con estos ahora y todo es jQuery con los servicios web. Mi vida es 100% más fácil y todo es mucho más rápido de implementar ... –

1

Después de muchos días de jugar un poco con esto, no he encontrado una solución adecuada para el problema, pero sí tienen una viable solución temporal .

CollapsiblePanelExtender se establece en NO postback automáticamente, lo que soluciona el problema de los datos eliminados que vuelven a aparecer cuando se abre el extensor. El otro problema, creo, está relacionado.

Parece que el ViewState para el repetidor no está sincronizado con los datos. e.CommandArgument no siempre es correcto y parece hacer referencia a los datos anteriores. Intenté solucionarlo almacenando los objetos ArrayList de MyDTO en ViewState al abrir el cuadro de diálogo modal y usar el ID recuperado de e.Item.ItemIndex para encontrar el elemento correcto para eliminar. Esto no funcionó correctamente, ArrayList sacó ViewState no estaba sincronizado.

Almacenar ArrayList en la sesión hace que todo funcione, lo que me lleva a creer que estoy haciendo algo fundamentalmente incorrecto o que hay una falla sutil en la versión del kit de herramientas que estoy usando (todavía estamos en VS2005 por lo que están atrapados con una versión anterior del kit de herramientas)

Disculpen si esto no tiene sentido, póngase en contacto conmigo si desea aclaración sobre algo.

1

tratar de usar

((IDataItemContainer) Container) .DataItem

en lugar de "Container.DataItem"

que trabajó para mí.