2010-06-09 13 views
5

In einem Benutzersteuerelement habe ich einen Repeater innerhalb eines UpdatePanel (welche ID innerhalb eines ModalPopupExtender angezeigt. Der Repeater ist datenbankgebunden mit einer Array-Liste von MyDTO-Objekten. Es gibt zwei Schaltflächen für Jedes Element in der Liste Nach der Bindung werden ImageURL und CommandArgument festgelegtUpdatePanel, Repeater, DataBinding Problem

Dieser Code funktioniert beim ersten Mal einwandfrei, aber das CommandArgument ist danach falsch.Es scheint als ob die Anzeige korrekt aktualisiert wird, aber der DTO ist nicht und der CommandArgument sended ist das, das gerade entfernt wurde.

Kann jemand irgendwelche Probleme mit dem Code feststellen?

Edit: Ich habe gerade einen CollapsiblePanelExtender zum Code hinzugefügt. Wenn ich jetzt ein Element lösche und das Panel erweitere, ist das Objekt, das zuvor gelöscht wurde (und aus dem Display verschwunden ist), zurück gekommen. Es scheint, dass der Repeater nicht korrekt unter der Motorhaube umgebaut wurde.

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

Gibt es in Ihrem 'ItemDataBound'-Handler Code? Innerhalb dieser Methode deklarieren Sie eine 'MyDTO'-Variable (' oQuery') und verwenden sie nie. –

+0

Entschuldigung, ja, ich habe es für die Kürze getrimmt –

Antwort

7

Vielen Dank, dass Sie mich daran erinnert haben, warum ich ASP.NET-Steuerelemente nicht mehr verwendet habe. Dies ist genau die Art von Albtraum, der zu viele Projekte über Budget und Zeitplan hinausgehen ließ.

Mein Rat an Sie ist, die einfachste Art zu denken, dies zu implementieren. Sie können versuchen, sich nach vorne zu beugen, um dies auf die ASP.NET-Art zu bringen oder den kürzesten Weg zu nehmen. Alles, was Sie tun, ist HTML zu generieren, sollte es nie so schwierig sein.

Die wahrscheinlichste Ursache für Ihr Problem ist, dass der ViewState auf der Seite gespeichert ist, die bei einem teilweisen Postback nicht aktualisiert wird. Mit jeder Änderung im Update-Panel postest du den ursprünglichen Viewstate der Seite.

Versuchen Sie, den Repeater durch eine einfache For-Schleife zu ersetzen (und ignorieren Sie die Leute, die sich beschweren, sollten Sie Markup und Code nicht mischen). Ersetzen Sie Ihre Datenbindungsanweisungen durch <%= %>. Das beseitigt den Ansichtszustand alle zusammen und sollte jede entfernte Zeile wieder erscheinen lassen.

+0

Sie sind völlig richtig, ich habe aufgehört, mit diesen jetzt zu kümmern und alles ist jQuery mit Webservices. Mein Leben ist 100% einfacher und alles ist viel schneller zu implementieren .. –

1

Nach vielen Tagen des Herumspielen mit diesem Ich habe keine richtige Lösung für das Problem, sondern tun haben eine tragfähige Behelfslösung gefunden .

Der CollapsiblePanelExtender wird automatisch auf NOT postback gesetzt, wodurch das Problem behoben wird, dass die gelöschten Daten beim Öffnen des Extenders wieder erscheinen. Das andere Thema ist meiner Meinung nach verwandt.

Es scheint, dass der ViewState für den Repeater nicht mit den Daten synchronisiert ist. e.CommandArgument ist nicht immer korrekt und scheint auf die vorherigen Daten zu verweisen. Ich versuchte es zu beheben, indem ich die ArrayList von MyDTO-Objekten in ViewState speicherte, wenn ich den Modal-Dialog öffnete und die ID aus e.Item.ItemIndex verwendete, um das richtige zu löschende Element zu finden. Dies funktionierte nicht richtig, die ArrayList, die aus dem ViewState herausgezogen wurde, war nicht mehr synchron.

Das Speichern der ArrayList in der Sitzung lässt alles funktionieren, was mich zu der Annahme verleitet, dass ich etwas fundamental falsch mache oder in der Version des Toolkits, die ich benutze, ein kleiner Fehler ist (wir sind noch dran) VS2005 so sind mit einer älteren Version des Toolkits stecken)

Entschuldigung, wenn dies keinen Sinn macht, kontaktieren Sie mich, wenn Sie etwas zu klären möchten.

1

Versuchen Sie es mit

((IDataItemContainer) Container) .DataItem

statt "Container.DataItem"

Es ist für mich gearbeitet.