简体   繁体   中英

How to render a WebUserControl client-side

I created a web user control which has some ASP.NET and third-party controls.

I've already tested my control in the markup of a page and it works well.

<APP:MyControl ID="myControl1" InitializeWithValue="Employee" />
<APP:MyControl ID="myControl2" InitializeWithValue="Supplier" />

Now, I want to render this control in the same page but not when the page renders at the first time. In fact, I will click a button which will call a callback and in that moment I want to render the control.

I was trying to do something like this.

void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)
{
   MyControl c1 = new MyControl();
   c1.InitializeWithValue = Person.Enum.Employee; //<--CRASH

   System.Text.StringBuilder sb = new System.Text.StringBuilder();
   System.IO.StringWriter sw = new System.IO.StringWriter(sb);
   HtmlTextWriter hw = new HtmlTextWriter(sw);
   c1.RenderControl(hw);
   return sb.ToString();
}

Then on my client-side receiver

<a href="javascript:void(0);" onclick="testcallback('', '')">Test</a>
<div id="divControls"></div>

<script>
    function receiver(arguments, context) {
        document.getElementById('divControls').innerHTML = arguments;
    }
</script>

But it crash at the moment of the initialization because all the inner controls of the WebUserControl are null. They have not been initialized.

This is the property of the control

   [Browsable(true)]
   public Person.Enum InitializeWithValue
   {
      get { return this.enumPersonValue; }
      set
      {
         this.enumPersonValue = value;
         //Literal control
         this.litPersonType.Text = "Employee"; //<-- CRASH because litPersonType is null.
      }
   }

Some can help me to correct this or suggest me another way render a web control but client-side?

UserControls usually are tighted to the Page Life Cycle, so you would need to recreate a whole page and render it instead.

Second, you should load your usercontrol using its .ascx file and not only its class, this is required because only your class is not enough.

You can still try to do like you was doing only creating but using Page.LoadControl :

void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)
{
   MyControl c1 = (MyControl)page.LoadControl("/Controls/myControl.ascx");
   c1.InitializeWithValue = Person.Enum.Employee; //<--CRASH

   System.Text.StringBuilder sb = new System.Text.StringBuilder();
   System.IO.StringWriter sw = new System.IO.StringWriter(sb);
   HtmlTextWriter hw = new HtmlTextWriter(sw);
   c1.RenderControl(hw);
   return sb.ToString();
}

But if your control has Events related to the Page Life Cycle you might need to create a whole context to it:

You can do it all like this:

using (var stringWriter = new StringWriter())
{
       using (var page = new Page())
       {
            MyControl myControl = (MyControl)page.LoadControl("/Controls/myControl.ascx");

            var head = new HtmlHead();
            page.Controls.Add(head);

            var form = new HtmlForm();
            page.Controls.Add(form);

            var div = new HtmlGenericControl("div");
            div.ID = "myControlContent";
            form.Controls.Add(div);

            div.Controls.Add(myControl);

            HttpContext.Current.Server.Execute(page, stringWriter, false);

        }
        return stringWriter.ToString()
}

Then in your JS you can parse the whole html and get only the innerHTML of div#myControlContent , for example:

function receiver(arguments, context) {
    var parser = new DOMParser();
    var doc = parser.parseFromString(arguments, "text/html");

    document.getElementById('divControls').innerHTML = doc.getElementById('myControlContent').innerHTML;
}

note that DOMParser , is available only in mordern browsers, but you can find other approachs for older browsers...

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