C#: Panel Resets Scroll Position after Focus is Lost and Regained


In an application that I have written there is a dashboard on the main form that is composed of a large docked scrollable panel that contains various other panels each showing various pieces of information. I have the AutoScroll property of the panel set to True so that if there are more modules/panels on the dashboard than can be visible on the screen, the user can scroll down to view them. When the user navigates to another window or another application, then returns to my application, and clicks one of the smaller panels on the dashboard, the large docked panel’s scroll position jumps up to the top. This was quite annoying as every time the user returned to my application they had to scroll back down to the module they were looking at previously.

Many of the solutions I found suggested manually setting the Panel.AutoScrollPosition when the form regains focus. The problem with this is that I would have had to capture the Click or MouseDown events of every single control on the form. I figured there had to be a better way to do this so I kept searching. I finally found a post on a forum that indicated that the issue was caused by the fact that the Panel.ScrollToControl method is called when my application regains focus. The ScrollToControl was scrolling to what the Panel control deemed to be the “activeControl” and thus caused the panel to jump to the top. So, to solve my problem, all I did was create a class that extended the Panel class and overrode the ScrollToControl method so that it returned the point associated with the currently visible portion of the panel.

public class CustomPanel : System.Windows.Forms.Panel
{
    protected override System.Drawing.Point ScrollToControl(System.Windows.Forms.Control activeControl)
    {
        // Returning the current location prevents the panel from
        // scrolling to the active control when the panel loses and regains focus
        return this.DisplayRectangle.Location;
    }
}

I presume that this might have side effects elsewhere but I haven’t found any so far in my situation.

About these ads

39 Responses to “C#: Panel Resets Scroll Position after Focus is Lost and Regained”

  1. n/a Says:

    Tank you for this vvery usefull Workaround :)

    • Nick Olsen Says:

      Glad it helped!

  2. Raymond Says:

    Thanks, realy helped me with this!

  3. Marcel de Vries Says:

    Thank You very much! Works like a charm!

    • Nick Olsen Says:

      No problem!

  4. Liqing Zhang Says:

    Thank you for this neat solution!
    It works for me!

    • Nick Olsen Says:

      I’m glad you found it useful!

  5. Samuel Says:

    Thanks a lot !!!!

  6. Quentin Says:

    This tip just saved my sanity!!!!

    I love you man and I love the InterWebs!

    • Nick Olsen Says:

      Glad it helped! I about went crazy over this as well!

  7. John Says:

    Thanks for sharing.

    A problem I encountered while using this is that adding controls to the panel (or increasing the size of the controls), will not cause the panel to autoscroll.

    For exemple, if you have textbox in the panel and the textbox’ height increases, the panel will not autoscroll and the user will have to “scroll down” manually.

  8. Leon Says:

    Amazing, it works! Thanks man!!

  9. TJ back Says:

    Thank you very much~
    You saved my life~ :)

  10. ZD Says:

    Hi Nick, you just saved my life, I’ve been on this darn thing for more than a f***kin month!! Thank you so much, God Bless

  11. Alan8 Says:

    Thanks Nick! This has fixed a long-standing problem.

    • Nick Olsen Says:

      No problem! I know how that feels. Glad it helped.

  12. aaa Says:

    Exactly what i’m looking for ,
    Thank you very very much

  13. Aaron Morabito Says:

    Excellent! This is the perfect fix! I was going crazy capturing all the clicks and setting that darn AutoScrollPosition!

  14. Vikas Says:

    How to implement this in C# with ASP.NET?

    • Nick Olsen Says:

      Copy and paste the code above into a class file that resides in its own dll or in you project. Then you can do one of two things. You can then add a standard Panel to your form and then edit the designer class of that form and change the declaration statement of that panel from a System.Windows.Forms.Panel object to a CustomPanel object. Or, you can right click the Toolbar and add a custom control that references the dll or the project in which you placed the CustomPanel class. That will create a new icon for the CustomPanel control in the Toolbox and you can simply drag and drop that onto your form.

  15. Johnson Says:

    SplitContainer has the same problem. And I try to resolve in your way. But it does not work.

  16. Mike Says:

    Hey Nick, thank you very much. If was dumbfounded by such a stupid problem.

  17. Norbert Kovacs Says:

    Simple and elegant solution!
    Thank you very much!

  18. R Says:

    This was one of the most useful tips I have ever got, thanks a million.

    -R

  19. Derek Owens Says:

    Wow, this is great! This absolutely made my day. I have a problem in a piece of software that has been bugging me and hindering my work for the past two years. This was the solution.

    Weight off my shoulders. Thanks a million.

  20. LordYabo Says:

    Total win. thanks, solved my problem!

  21. Sergey Says:

    Thanks a lot for this simple and elegant solution!

  22. Royalblue Says:

    Thanks a lot for this simple and wonderfull solution

  23. Tristan Says:

    Thank you! I beat my head against a wall for a while trying to fix this.

  24. Subha Says:

    Hi Nick, thank for this post. It saved a lot of time. I was struggling to find out a viable solution for this behavior of System.Windows.Form.Panel control.

    Thanks a ton.
    Subha

  25. Amnon Says:

    thanks! useful!

  26. Siva Says:

    This is an excellent vivid solution mate…much appreciated…thnkx a lot… :)

  27. ashok Says:

    Thanks a lot friend. your solution does work for my project.

  28. Murilo Fujita Says:

    Hello, Olsen!
    I am a beginner in programming and I need a little help.
    I created programmaticaly panels each 300 images. I used your class and works well for 1 panel. How do I call this class if focus is in a second ou third panel? I tried:
    if (panel2 != null)
    { CustomPanel customPanel = new CustomPanel();
    customPanel.ScrollToControl(panel2);
    }
    but the visibility for CustomPanel is protected and my form doesn´t see the method. How can I fix it?
    Congratulation and thank you very much.

  29. Murilo Fujita Says:

    Hi! Despite my message was erased, I would like to share a solution.
    I asked what was necessary to created other panels that inherit properties from CustomPanel. That´s it:
    Panel panel2 = new CustomPanel();
    if you need more panels, continue the idea:
    Panel panel3 – new CustomPanel();
    Thank you for your text! Very useful!
    Best regards!

  30. Allan Tong Says:

    Thank you, Nick. Great post!

  31. Assaf Says:

    Hi, Nick
    4 years after your post continue to save the world
    I’m a SW-Eng at a big American company
    And your solution helped like magic
    Thanks, Assaf

  32. Younes Says:

    Thank you very very much!

  33. D. Says:

    Thx!


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 68 other followers

%d bloggers like this: