Click here to Skip to main content
15,867,594 members
Articles / Web Development / ASP.NET
Article

A "stateful" scrollable panel

Rate me:
Please Sign up or sign in to vote.
4.86/5 (14 votes)
8 Nov 2006CPOL2 min read 114.6K   1.4K   38   27
A scrollable panel retaining its scroll position across postbacks.

After postback before restoring scroll position

Scroll position restored

Introduction

Often, we wrap a GridView inside a panel with the "overflow:scroll" style set and expect the user to scroll and select a GridView item to work with. The problem is that whenever the page is posted back, the selected item is not visible because the panel scroll position has been reset.

At our latest project, we needed such a functionality, but could not find anything similar, so we decided to code it ourselves. The result is the "StatefulScrollPanel", a custom control that retains its scroll position across postbacks.

Background

Basically, all we need is some basic knowledge of JavaScript and an elementary overriding of two of asp:Panel's own methods. We start with two hidden fields that accompany our control and whose purpose is to keep track of the scrollTop and scrollLeft properties of the panel (div). These, along with the method that keeps track of the control's scroll position, are rendered just before our control, so we override the Render(HtmlTextWriter) method. Since we do want the control to be displayed with no trouble at design time, we simply delegate to the parent if in design mode:

C#
protected override void Render(HtmlTextWriter writer)
{                        
    if (DesignMode)
    {
        base.Render(writer);
        return;
    }

    /*
     * Hidden inputs to persist scroll position(s)
     */
    writer.Write("<input type='hidden' name='" + 
                ScrollXInputId + "' id='" +
                ScrollXInputId + "' value='" + 
                ScrollXInputValue + "'/>");
    
    writer.Write("<input type='hidden' name='" + 
                 ScrollYInputId + "' id='" + 
                 ScrollYInputId + "' value='" + 
                 ScrollYInputValue + "'/>");
    
    //Trace method that populates the hidden inputs
    writer.Write("<script language='Javascript'>function " + 
                 TraceMethod + "{" + GetElementAccessor(ScrollXInputId) + 
                 ".value = " + GetElementAccessor(ClientID) +  
                 ".scrollLeft;" + GetElementAccessor(ScrollYInputId) +  
                 ".value = " + GetElementAccessor(ClientID) + 
                 ".scrollTop;}" + "</script>");

    //Delegate core rendering to momma
    base.Render(writer);                      
}

The GetElementAccessor(String) method, and the Scroll[X|Y]InputId, Scroll[X|Y]InputValue, and TraceMethod properties are helpers used to reduce the code we have to write. Take a look at the control's code to see their definitions.

All we have to do now is to register the trace method with our control during the OnLoad(EventArgs) event and set the scroll position:

C#
protected override void OnLoad(EventArgs e)
{
    //To enable scrolling in the first place
    base.Style.Add(HtmlTextWriterStyle.Overflow, "scroll");
    
    //Register our trace method
    base.Attributes.Add("onScroll", TraceMethod);            

    //On start up set scroll position(s) to the existing one
    Page.ClientScript.RegisterStartupScript(GetType(), AdjustScriptKey, 
        GetElementAccessor (ClientID) + ".scrollLeft = " + 
                ScrollXInputValue + ";" + 
            GetElementAccessor(ClientID) + ".scrollTop = " + 
                ScrollYInputValue + ";", 
        true);
    
    base.OnLoad(e);
}

That's it!

Using the code

Using the control is as simple as using the asp:Panel control itself. We drop it in our aspx pages, and set its Width and Height properties:

HTML
<cc1:StatefullScrollPanel ID="StatefullScrollPanel1" 
        runat="server" Width="250px" height="105px">
Panel elements go here           
</cc1:StatefullScrollPanel>

Note that we do not have to explicitly set the overflow style since the control takes care of that. Also note that we can use as many controls we need on the same page since the produced code is unique for each control instance. We have tested the code with Firefox 2.0 and IE 6.0, and seems to be working fine.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect www.neurocom.gr
Greece Greece
Working in sunny Greece as a software engineer since 1998. Currently spending most of my time coding solutions for the telecommunications sector using Java, .Net, Oracle and PostgresSQL.

Comments and Discussions

 
QuestionUnable to get this working in VS 2012 Pin
Member 880869321-May-14 8:12
Member 880869321-May-14 8:12 
GeneralThis was great Pin
laurie nash17-Sep-09 5:22
laurie nash17-Sep-09 5:22 
GeneralHaving a problem with this control inside a Multiview Pin
smolino18-Jun-08 6:36
smolino18-Jun-08 6:36 
GeneralRe: Having a problem with this control inside a Multiview Pin
s.oikonomopoulos18-Jun-08 8:56
s.oikonomopoulos18-Jun-08 8:56 
GeneralExactly what I need Pin
AdeleLeRoux4-May-08 1:42
AdeleLeRoux4-May-08 1:42 
NewsGreat Control - Improvement for only Vertical Scrolling Pin
Marc Riffel26-Mar-08 3:53
Marc Riffel26-Mar-08 3:53 
QuestionNext step - how to force scroll position to top or bottom programmatically? Pin
ehinton3-Jan-08 6:30
ehinton3-Jan-08 6:30 
GeneralRe: Next step - how to force scroll position to top or bottom programmatically? Pin
s.oikonomopoulos3-Jan-08 22:57
s.oikonomopoulos3-Jan-08 22:57 
GeneralRe: Next step - how to force scroll position to top or bottom programmatically? Pin
ehinton4-Jan-08 3:51
ehinton4-Jan-08 3:51 
GeneralFixed: Re: Next step - how to force scroll position to top or bottom programmatically? Pin
ehinton4-Jan-08 6:49
ehinton4-Jan-08 6:49 
GeneralRe: Fixed: Re: Next step - how to force scroll position to top or bottom programmatically? Pin
s.oikonomopoulos7-Jan-08 2:28
s.oikonomopoulos7-Jan-08 2:28 
GeneralProblem (and fix) when hidden in a multiview Pin
MrT99916-Oct-07 5:36
MrT99916-Oct-07 5:36 
Generalstateful scrollable panel Pin
Larry Swarts26-May-07 5:38
Larry Swarts26-May-07 5:38 
GeneralDoesn't Seem to Work in AJAX UpdatePanel Pin
cavedog68-May-07 3:45
cavedog68-May-07 3:45 
GeneralRe: Doesn't Seem to Work in AJAX UpdatePanel Pin
s.oikonomopoulos8-May-07 22:28
s.oikonomopoulos8-May-07 22:28 
I guess you should call the generated script from this part of the code behind:

<br />
//On start up set scroll position(s) to the existing one<br />
Page.ClientScript.RegisterStartupScript(GetType(), AdjustScriptKey, <br />
GetElementAccessor (ClientID) + ".scrollLeft = " + <br />
                ScrollXInputValue + ";" + <br />
            GetElementAccessor(ClientID) + ".scrollTop = " + <br />
                ScrollYInputValue + ";", <br />
        true);<br />


as soon as the call to the AJAX update returns. Remember that there is no postback in this case so the code does not get a chance to run.
GeneralRe: Doesn't Seem to Work in AJAX UpdatePanel Pin
zetarho10-May-07 23:48
zetarho10-May-07 23:48 
GeneralRe: Doesn't Seem to Work in AJAX UpdatePanel Pin
s.oikonomopoulos15-May-07 1:17
s.oikonomopoulos15-May-07 1:17 
GeneralRe: Doesn't Seem to Work in AJAX UpdatePanel Pin
MiaF18-May-07 4:29
MiaF18-May-07 4:29 
GeneralRe: Doesn't Seem to Work in AJAX UpdatePanel Pin
s.oikonomopoulos22-May-07 2:30
s.oikonomopoulos22-May-07 2:30 
GeneralRe: Doesn't Seem to Work in AJAX UpdatePanel Pin
MiaF23-May-07 2:11
MiaF23-May-07 2:11 
GeneralRe: Doesn't Seem to Work in AJAX UpdatePanel Pin
southernpost28-Jun-07 6:18
southernpost28-Jun-07 6:18 
QuestionThis really works! Pin
Hans Wijtvliet5-Apr-07 4:32
Hans Wijtvliet5-Apr-07 4:32 
GeneralJust what I've been looking for! Pin
sth_Weird29-Mar-07 20:05
sth_Weird29-Mar-07 20:05 
Generali have a problem Pin
EEmaan14-Mar-07 19:54
EEmaan14-Mar-07 19:54 
GeneralRe: i have a problem Pin
s.oikonomopoulos15-Mar-07 10:29
s.oikonomopoulos15-Mar-07 10:29 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.