Click here to Skip to main content
15,885,216 members
Articles / Desktop Programming / MFC

Better Algorithm for Finding UpdatePanel that will be Updated During Page Request

Rate me:
Please Sign up or sign in to vote.
4.00/5 (1 vote)
18 May 2013CPOL2 min read 10.3K   5
A better algorithm for finding UpdatePanel that will be updated during page request

Introduction

The other day, I was experimenting with finding which UpdatePanel will be updated during page postback.

I found out that my solution was not working correctly for complex triggers, like user controls with custom events, which will trigger async postbacks and update of panel.

Or for grids with buttons. It was a big issue. Also it was not pointing to the correct UpdatePanel if name of the control was not entirely unique (for example, when you have multiple same custom controls on page). It would return the first panel, even if it wasn't updating.

So here is the updated code:

C#
public static UpdatePanel FindAsyncPostBackUpdatePanel(this Page page)
{
    var scriptManager = ScriptManager.GetCurrent(page);
    var pageRequestMngr = scriptManager.GetNonPublicProperty
    <object>("PageRequestManager");
    var updatePanels = pageRequestMngr.GetNonPublicField
    <List<UpdatePanel>>("_allUpdatePanels");
    var source = page.FindControl(scriptManager.AsyncPostBackSourceElementID);
    UpdatePanel parentUp = null;
    //check if is child of update parent with children as triggers
    Control parent = source.Parent;
    while (parent != null && parentUp == null)
    {
        parent = parent.Parent;
        parentUp = parent as UpdatePanel;
        if (parentUp != null && (CheckIfPostbackSourceInTriggers
        (source, parentUp) || parentUp.ChildrenAsTriggers
            || (parentUp.IsInPartialRendering || 
            parentUp.GetNonPublicProperty<bool>("RequiresUpdate"))))
        {
            break;
        }
        parentUp = null;
    }
    if (parentUp != null) return parentUp;
    foreach (var up in updatePanels)
    {
        if (CheckIfPostbackSourceInTriggers(source, up))
            return up;
    }
    return null;
}

private static bool CheckIfPostbackSourceInTriggers(Control source, UpdatePanel up)
{
    foreach (var trigger in up.Triggers)
    {
        var t = trigger as AsyncPostBackTrigger;
        if (t == null)
        {
            continue;
        }
        if (t.GetNonPublicField<Control>
        ("_associatedControl").UniqueID == source.UniqueID)
        {
            return true;
        }
    }
    return false;
}

What has Changed?

  1. I added code for traversing parent controls of our source control. Most of the time control that is causing post back is children of UpdatePanel. Such a loop is much quicker than finding out all of UpdatePanels, and checking its triggers.

    Also if grid with some grid-specific event caused UpdatePanel to update, this grid probably will be child of UpdatePanel and so will be button from that grid. Still it's not ideal. If you have grid with some entities (customers for example), and you want to click at some customer will open its edit view in UpdatePanel in some other part of page. Source and UpdatePanel are not in child-parent relation.

    If source is child of UpdatePanel method will check if ChildrenAsTriggers is true - panel will be updated because it's triggered by child.

    If IsInPartialRendering flag and RequiresUpdate, after some test I can say that that this flag indicates if UpdatePanel will be updated. The interesting thing is that the first flag was not true even if given UpdatePanel was indeed updating. I don't know why. But the second flag non-public property was true in those situations.

  2. Checking only for control Id was not reliable since it doesn't have to be unique for page. That's why I am checking for unique id, of non-public field with trigger control instance and source unique id. That has to give the correct answer only for one control, but is much slower since it is using reflection.

That's it for now, but I feel that I will have to revise that code once again soon. Smile

License

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


Written By
Software Developer
Poland Poland
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionSome Changes Pin
culson27-May-14 11:45
culson27-May-14 11:45 
AnswerRe: Some Changes Pin
n.podbielski28-May-14 1:14
n.podbielski28-May-14 1:14 
GeneralMy vote of 4 Pin
Ramu Sangabathula Original18-May-13 16:16
Ramu Sangabathula Original18-May-13 16:16 
SuggestionUpdate Panels are heavy Pin
Ramu Sangabathula Original18-May-13 16:15
Ramu Sangabathula Original18-May-13 16:15 
GeneralRe: Update Panels are heavy Pin
n.podbielski18-May-13 22:31
n.podbielski18-May-13 22:31 

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.