简体   繁体   中英

Begin/EndRequestHandler multiple handlers in custom ASP.NET controls

I have a custom ASP.NET control, a dropdown/treeview, which needs to add Begin(End-)RequestHandlers to prevent scrolling to the top of container during UpdatePanel partial postbacks (as described here ). They are added dynamically like so:

Page.ClientScript.RegisterStartupScript(this.GetType(), this.ClientID, string.Format(@"
                  var xPos, yPos;
                  var prm = Sys.WebForms.PageRequestManager.getInstance();

                  function BeginRequestHandler(sender, args) {{
                    if ($get('{0}') != null) {{
                      // Get X and Y positions of scrollbar before the partial postback
                      xPos = $get('{0}').scrollLeft;
                      yPos = $get('{0}').scrollTop;
                    }}
                 }}

                 function EndRequestHandler(sender, args) {{
                     if ($get('{0}') != null) {{
                       // Set X and Y positions back to the scrollbar
                       // after partial postback
                       $get('{0}').scrollLeft = xPos;
                       $get('{0}').scrollTop = yPos;
                     }}
                 }}

                 prm.add_beginRequest(BeginRequestHandler);
                 prm.add_endRequest(EndRequestHandler);  ", this.ItemsContainer.ClientID), true);

The problem begins when I add more than one instance of the control to the page. Both scripts are rendered and registered BUT in the end only one, the last one on the page, ends up attached to the the containers, ie. wherever there is update in panel X or Y, only the JS for panel Y is executed - twice!

A better option would surely be appending just one pair of Begin/End handlers, which I could perform by, for example, adding a static key for the RegisterStartupScript method. The only problem is that I would need to pass a parameter of the panel for currently updating UpdatePanel.

Any idea how to do this, and combine with the above?

This modification automatically restores the scroll position of all panels.

<script type="text/javascript">
    (function () {
        var scrolledDivs = [];
        var prm = Sys.WebForms.PageRequestManager.getInstance();

        prm.add_beginRequest(function (sender, args) {

            //store the scroll positions of all "scrolled" div elements
            //UpdatePanel and Panel both are div elements
            scrolledDivs = [];

            $('div').each(function () {
                var div = $(this);
                if (div.scrollLeft() != 0 || div.scrollTop() != 0) {
                    scrolledDivs.push({
                        element: this,
                        scrollLeft: div.scrollLeft(),
                        scrollTop: div.scrollTop()
                    });
                }
            });
        });

        prm.add_endRequest(function (sender, args) {
            //restore scroll positions
            $.each(scrolledDivs, function (index, value) {
                $(value.element).scrollLeft(value.scrollLeft).scrollTop(value.scrollTop);
            });
        });
    })();
</script>

Note: you need to include JQuery

Using a bit modified code from LostInComputer the solution looks like this:

            Page.ClientScript.RegisterStartupScript(this.GetType(), "scrollRestorer", @"
                  var scrolledDivs = [];
                  var prm = Sys.WebForms.PageRequestManager.getInstance();

                  function BeginRequestHandler(sender, args) {
                    //store the scroll positions of all 'scrolled' div elements
                    //UpdatePanel and Panel both are div elements
                    scrolledDivs = [];

                    $('div').each(function () {
                        var div = $(this);
                        if (div.scrollLeft() != 0 || div.scrollTop() != 0) {
                            scrolledDivs.push({
                                element: this.id,
                                scrollLeft: div.scrollLeft(),
                                scrollTop: div.scrollTop()
                            });
                        }
                    });
                 }

                 function EndRequestHandler(sender, args) {
                    //restore scroll positions
                    $.each(scrolledDivs, function (index, value) {
                        $('#' + value.element).scrollLeft(value.scrollLeft).scrollTop(value.scrollTop);
                    });
                 }

                 prm.add_beginRequest(BeginRequestHandler);
                 prm.add_endRequest(EndRequestHandler);  ", true);

The item itself cannot be stored in array, only ID should be stored.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM