5 Stimmen

UpdatePanel, Repeater, DataBinding Problem AktualisierungsPanel, Repeater, DataBinding Problem

In einem Benutzersteuerelement habe ich einen Repeater innerhalb eines UpdatePanels (das innerhalb eines ModalPopupExtender angezeigt wird. Der Repeater ist datengebunden mit einer Arrayliste von MyDTO-Objekten. Für jedes Element in der Liste gibt es zwei Schaltflächen. Beim Binden werden die ImageURL und das CommandArgument festgelegt.

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

Kann jemand Probleme im Code erkennen?

Bearbeiten: Ich habe gerade einen CollapsiblePanelExtender zum Code hinzugefügt. Wenn ich jetzt ein Element lösche und das Panel erweitere, ist das zuvor gelöschte Element (und aus der Anzeige verschwunden) zurückgekehrt. Es scheint, dass der Repeater unter der Haube nicht korrekt neu aufgebaut wurde.

ASCX

            Name
             

                <%#((MyDTO)Container.DataItem).Name%>

                    Beschreibung : 
                    <%#((MyDTO)Container.DataItem).Description%>

                    Suchtext : 
                    <%#((MyDTO)Container.DataItem).Text%>

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)
    {
        //laden der initialen Daten..
        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)
                { 
                  //etwas tun
                }
                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();
    }

7voto

Marnix van Valen Punkte 12667

Danke, dass du mich daran erinnerst, warum ich aufgehört habe, ASP.NET-Steuerlemente zu verwenden. Dies ist genau die Art von Albtraum, die zu vielen Projekten geführt hat, die viel über Budget und Zeitplan hinausgingen.

Mein Ratschlag an dich ist, darüber nachzudenken, wie man dies am einfachsten implementieren kann. Du kannst versuchen, dich übermäßig anzustrengen, um dies auf die ASP.NET-Art zum Laufen zu bringen, oder den kürzesten Weg nehmen. Du generierst nur HTML, es sollte nie so schwierig sein.

Die wahrscheinlichste Ursache für dein Problem ist, dass der ViewState auf der Seite gespeichert wird, was bei einem teilweisen Postback nicht aktualisiert wird. Bei jeder Änderung im Update-Panel sendest du das initiale ViewState der Seite zurück.

Versuche den Repeater durch eine einfache for-Schleife zu ersetzen (und ignoriere die Leute, die anfangen zu beschweren, dass du Markierung und Code nicht vermischen solltest). Ersetze deine Datenbindungsanweisungen durch <%= %>. Das beseitigt den ViewState vollständig und sollte verhindern, dass entfernte Zeilen wieder auftauchen.

1voto

Gordon Thompson Punkte 4554

Nachdem ich viele Tage damit herumgespielt habe, habe ich keine richtige Lösung für das Problem gefunden, aber ich habe einen funktionierenden Workaround.

Der CollapsiblePanelExtender ist so eingestellt, dass er nicht automatisch zurückgesendet wird, was das Problem des erneuten Erscheinens der gelöschten Daten beim Öffnen des Extenders behebt. Das andere Problem, glaube ich, hängt damit zusammen.

Es scheint, dass der ViewState für den Repeater nicht mit den Daten synchron ist. e.CommandArgument ist nicht immer korrekt und scheint sich auf die vorherigen Daten zu beziehen. Ich habe versucht, es zu beheben, indem ich das Arraylist von MyDTO-Objekten im ViewState speichere, wenn ich den Modal-Dialog öffne und die ID, die aus e.Item.ItemIndex abgerufen wurde, verwende, um das richtige Element zum Löschen zu finden. Das hat nicht richtig funktioniert, das Arraylist aus dem ViewState war nicht synchron.

Das Speichern des Arraylists in der Session lässt alles funktionieren, was mich glauben lässt, dass ich etwas grundlegend falsch mache oder es einen subtilen Fehler in der Version des Toolkits gibt, die ich verwende (wir verwenden immer noch VS2005 und sind daher auf eine ältere Version des Toolkits festgelegt).

Entschuldigung, wenn das keinen Sinn ergibt, kontaktiere mich, wenn du eine Klarstellung zu irgendetwas benötigst.

1voto

Kiran Punkte 111

Versuchen Sie, zu verwenden

((IDataItemContainer)Container).DataItem

anstatt "Container.DataItem"

Es hat bei mir funktioniert.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X