Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Asynchronous loading of user controls in a page

I have created a page to display multiple user controls inside update panels. Some user controls will get loaded faster and some may take a longer time to load. Now when the page loads, it waits for all the user controls to get loaded and display the page only after that. But I want to load the user controls asynchronously with a loader image for each of them so that the light weight user controls will get loaded easily without waiting for the heavier ones.

Please help me to find a solution.


I have successfully loaded the user control into my page using the above method. However now i am facing difficulty in loading usercontrols containing ajax controls such as tab container, calender extender etc..

Is there any work around for this problem

like image 434
Suhaib Avatar asked Nov 28 '11 12:11

Suhaib


1 Answers

You will run into a bunch of issues: ViewState, controls needing form tags, postbacks will not work but if you are doing this with a control that is purely a View it will work fine.

Script:

//use .ready() or pageLoad() and pass params etc if you need to
$.ajax({
    type: 'POST',
    url: 'Default.aspx/GetControlViaAjax',
    data: "{}",
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function (data) {  
      $('#yourdiv').html(data.d);
    }
 });

WebMethod:

    [WebMethod]
    public static string GetControlViaAjax()
    {
        //example public properties, send null if you don't have any
        Dictionary<string, object> d = new Dictionary<string, object>();
        d.Add("CssClass", "YourCSSClass");
        d.Add("Title", "Your title");
        return RenderUserControl("/yourcontrol.ascx", true, d, null, null);
        //use this one if your controls are compiled into a .dll
        //return RenderUserControl(null, true, d, "Com.YourNameSpace.UI", "AwesomeControl");

    }  

Render method:

    private static string RenderUserControl(string path, bool useFormLess,
         Dictionary<string, object> controlParams, string assemblyName, string controlName )
    {

        Page pageHolder = null;
        if (useFormLess)
        {
            pageHolder = new FormlessPage() { AppRelativeTemplateSourceDirectory = HttpRuntime.AppDomainAppVirtualPath }; //needed to resolve "~/"
        }
        else
        {
            pageHolder = new Page() { AppRelativeTemplateSourceDirectory = HttpRuntime.AppDomainAppVirtualPath };
        }

        UserControl viewControl = null;

        //use path by default
        if(String.IsNullOrEmpty(path))
        {    
            //load assembly and usercontrol when .ascx is compiled into a .dll        
            string controlAssemblyName = string.Format("{0}.{1},{0}", assemblyName, controlName );

            Type type = Type.GetType(controlAssemblyName);            
            viewControl = (UserControl)pageHolder.LoadControl(type, null);
        }
        else
        {
            viewControl = (UserControl)pageHolder.LoadControl(path);    

        }              

        viewControl.EnableViewState = false;

        if (controlParams != null && controlParams.Count > 0)
        {
            foreach (var pair in controlParams)
            {
                Type viewControlType = viewControl.GetType();
                PropertyInfo property =
                   viewControlType.GetProperty(pair.Key);

                if (property != null)
                {
                    property.SetValue(viewControl, pair.Value, null);
                }
                else
                {
                    throw new Exception(string.Format(
                       "UserControl: {0} does not have a public {1} property.",
                       path, pair.Key));
                }
            }
        }

        if (useFormLess)
        {                
            pageHolder.Controls.Add(viewControl);
        }
        else
        {
            HtmlForm form = new HtmlForm();
            form.Controls.Add(viewControl);
            pageHolder.Controls.Add(form);
        }
        StringWriter output = new StringWriter();
        HttpContext.Current.Server.Execute(pageHolder, output, false);
        return output.ToString();
    }

FormlessPage class:

    public class FormlessPage : Page
    {
        public override void VerifyRenderingInServerForm(Control control)
        {
        }
    }
like image 162
rick schott Avatar answered Oct 15 '22 06:10

rick schott