Heute in den Newsgroups [2], es fragte Fabian Nowothnik danach wie man nach einem Postback die Scrollpositionen von einzelnen Elementen wieder herstellen kann.
Für die Scrollposition der Seite gibt es dies ja seit ASP.NET 2.0 schon in der Serienausstattung. Ein Scrolling innerhalb eines DIV-Elements "passiert" ja schnell, in dem innerhalb eine DIV-Elements mehr reinpackt als die festgesetzen Ausmaße zulassen. Nun einfach den CSS-Style "overflow:auto;" oder "overlow:scroll;" gesetzt dann kann man darin scrollen, jedoch verliert sich die Scroll-Position nach dem Postback. Das ist schade.
Prinzipiell sollte es doch ganz einfach sein etwas dagegen zu machen. Position der Elemente vor dem Postback merken und dann direkt einfach beim neuladen wieder herstellen. Wäre doch auch nett wenn man dies dann einfach via kleinem Control machen kann einfach auf jeder Seite einsetzen kann. Gesagt getan, hier ist das Ergebnis das "RememberElementScrollPosition" WebControl für ASP.NET 2.0 :).
Gleich vorweg, dazu ist JavaScript notwendig, ohne geht's nicht. Die Anwendung selbst ist denkbar einfach. Nachdem man den Quelltext [1] in eine Assembly oder App_Code Ordner gepackt hat muss man das Control dem Web bekannt machen, dazu in der Web.config zu der Controls-Auflistung hinzufügen, hier ein Beispiel, es muss den eigenen Gegebenheiten angepasst werden.
<system.web>
<pages>
<controls>
<add namespace="DerAlbert.Community.Web.UI.WebControls"
assembly="DerAlbert.Community.Web"
tagprefix="dac" />
</controls>
</pages>
</system.web>
Auf der Seite dann folgendes
<dac:rememberelementscrollposition id="RESP1" runat="server">
<dac:controlid>MyPanel</dac:controlid>
<dac:controlid>Div1</dac:controlid>
</dac:rememberelementscrollposition>
Für jedes Element/Control ein <dac:ControlID/> hinzufügen. Es wird erst das passenden Server-Control gesucht und verwendet, wird keins gefunden so wird die angegebene ID direkt als ClientID verwendet. So das man
<asp:panel id="MyPanel" runat="server">Der rieisige Inhalt</asp:panel>
oder auch
<div id="Div1">Größer, schneller weiter</div>
verwenden kann. Je nach Vorliebe, aber eine ID muss vorhanden sein. Mehr muss man nicht machen.
Damit ich vor dem Postback die Daten auslesen kann Registriere ich mir mit ClientScript.RegisterOnSubmitStatement() eine Javascript Anweisung welche das sammeln der Scrollpositionen aufruft und in einem HiddenField ablegt, damit diese den Postback ohne weitere Tricks überleben. Beim wiederladen der Seite sollen die gespeicherten Positionen wieder gesetzt werden, dafür muss wieder eine JavaScript Anweisung registriert werden diesmal mit ClientScript.RegisterStartupScript(). Damit wird die übergebenen Anweisung ans Ende der Seite gelegt und automatisch aufgerufen nachdem der eigentliche Seiteninhalt schon vorhanden ist.
Das JavaScript selbst ist objektorientiert aufgebaut, sollte jedoch nicht so schwer sein zu verstehen. Es merkt sich die scrollTop und scrollLeft Werte des HTML-Elements und packt diese zusammen mit der ID des Elements in das Hiddenfield. Selbstverständlich für alle angebenen Elemente, jedoch nur wenn man die Element auch wirklich in einem "gescrolltem" Zustand sind. Nun genug geredet. Nutzt das Teil wenn Ihr wollt.
[1] Download Quelltext
[2] Newsgroup-Anfrage