Click here to Skip to main content
15,885,546 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 115K   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 
This stuff is fantastic, it preserves scroll position nicely (including the fix provided for situation where panel might not be visible.)

My next problem is, how can I force the scroll position to top or bottom?

I have a GridView inside the scrolling panel, and the gridview can be very long. One of our interface conventions is to have buttons that jump you immediately to the top or bottom of the grid. I have my code to change the currently selected GridView row working. But I am not having any luck getting the scroll position changed. I tried rendering javascript in onclick handlers for the two buttons that would cause the saved Y scroll position of the scrolling panel to be set to the appropriate scroll position for top or bottom (calculated), but the scroll position doesn't change. The buttons definitely trigger the javascript to execute but for some reason the position doesn't change. Here's the javascript rendered for scrolling to the top:

function ScrollToTop(me)
{
document.getElementById('WUCCodingWorklistPage_WUCNewItemsWorklist_pnlContainer').ScrollTop=0;
WUCCodingWorklistPage_WUCNewItemsWorklist_pnlContainerScrollToTop();
}

and here is the relevant generated stuff for pnlContainerScrollToTop():

input type='hidden' name='WUCCodingWorklistPage_WUCNewItemsWorklist_pnlContainerScrollTop' id='WUCCodingWorklistPage_WUCNewItemsWorklist_pnlContainerScrollTop' value='0'

function WUCCodingWorklistPage_WUCNewItemsWorklist_pnlContainerScrollToTop()
{
document.getElementById('WUCCodingWorklistPage_WUCNewItemsWorklist_pnlContainerScrollY').value= document.getElementById('WUCCodingWorklistPage_WUCNewItemsWorklist_pnlContainerScrollTop').value;
}

For some reason, the pane doesn;t scroll when this gets called. I've tried it two ways. One way (what I need to work) is when I have both a client side handler and a server side handler for the bottom to go to the top is clicked. The client side handler executes first, and then the server side handler, so I would expect the above javascript code to change the Y scroll position to 0 and save it in the hidden field, then when the server side handler finishes and the page comes back I would expect that to be the restored scroll position. Since that wasn't working, I tried removing the server side OnClick handler to see if just the scrolling would work without a server side call involved, but it still doesn;t work. Something about the above is not causing scroll position to ever change, but I am not understanding why.

Perhaps one of you who has also tried and/or adapted this terrific scrolling panel solution will have an idea why i can't force scrolling to top (or bottom), or perhaps one of you has done this and can provide a solution that works.

Thanks!
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 
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.