Travails of an ungeeker

Tuesday, March 14, 2006

ASP.NET User Control - accessing InnerHtml

We have a user control using DHTML that displays a button which when clicked renders a floating DIV layer with an image. It is easy to define global string variables that are set from attributes of the user control to pass parameters for the image to show and caption, but then we wanted to inject HTML from between the opening and closing tags of the User control. Creating another element for this was ruled out because this would make the control too hard for our HTML designers to use.

I could not find a solution on the internet and until someone tells me a better one, here is a technique that works:
  1. Define a global property in the User Control with public accessor called Span.
  2. Place an opening and closing SPAN tag between the opening and closing tags of the User Control.
  3. Place your HTML code inside the SPAN.
Now you can access your HTML with Span.InnerHtml. In the case we had we also did the following to inject the user's HTML into the HTML of the User control and did the following.
  1. Add a Literal control to the design view of the User control in the place where the additional HTML should be injected.
  2. In the User control code, override the Render method (Note constructor cannot be used as the control has not been instantiated yet)
  3. Set the literal's Text property to the Span.InnerHtml property. (For gotchas, using Render, you have to check that your span object is not null because it is called several times, and remember to call base.Render(writer);
For the record, Blogger needs to provide some support for quoting code - especially indent formatting. I deleted the code I had from here because I could not make it render in Blogger acceptably. Sorry.

3 Comments:

  • This has been so very helpful. Not sure if you'll be checking the comments for a post you made two and a half years ago, but I thank you nonetheless.

    By Blogger Ooble, at 2:38 pm  

  • Great article. I'm currently using this method for easily duplicating CSS-driven rounded boxes, since you need 4 (or more) divs just to get the corners to look right, and it's annoying having to copy/paste "layout" html over and over.

    For those looking to do this as well, here are some further tips:

    1) The "Span" property described above is totally subjective, just make sure that the property name matches the html "tag" you place inside the user control, taking case-sensitivity into account for C# projects.

    IE, in the user control's code behind, put:

    ------
    public HtmlGenericControl MyContent { get; set; }
    ------

    Then, in the web form that consumes the user control, you'd have something like:

    ------
    <uc1:MyUserControl ID="MyUserControl1" runat="server"><MyContent>(Put your "inner html" content here)</MyContent></uc1:MyUserControl>
    ------

    2) Using ASP.NET 3.5, I was receiving an error trying to use the InnerHTML property of the literal in the Render event of the control. So instead, I just iterated through the "MyContent" controls and added each one to my user control, like I show below. (Assume that I have a div in my user control with the ID of "MyDiv", which will contain all of the "inner html" I want to add to the user control)

    protected override void Render(HtmlTextWriter writer)
    {
         if (MyContent != null)
         {
              for (int i = 0; i < MyContent.Controls.Count; i++)
              {
                   MyDiv.Controls.Add(MyContent.Controls[i]);
              }
         }

         base.Render(writer);
    }

    This ensures that all of the content between your opening closing <uc1:> tags will be added to your control.

    By Blogger itzkakarot, at 8:42 pm  

  • FYI, as each control is added from "MyContent" to "MyDiv" as shown above, the control is effectively removed from "MyContent", so you'll need to decrement "i" by one as you iterate through the loop. Like this:

    protected override void Render(HtmlTextWriter writer)
    {
        if (MyContent != null)
        {
            for (int i = 0; i < MyContent.Controls.Count; i++)
            {
                MyDiv.Controls.Add(MyContent.Controls[i]);
                i--;
            }
        }

        base.Render(writer);
    }

    By Blogger itzkakarot, at 4:17 pm  

Post a Comment

<< Home