Click here to Skip to main content
Licence 
First Posted 10 Aug 2004
Views 51,125
Bookmarked 30 times

Convert a Usercontrol to a WebControl

By | 10 Aug 2004 | Article
You've created a beautiful usercontrol with HTML layout but you want to use it as a Server Control. This macro generates the instantiation and render code for you.

Introduction

Ever written a nice usercontrol and wanted to migrate it to a webcontrol? Then you'll know you have to write a lot of render and initialization stuff yourself. With this macro, some of it is generated out of the .ascx file you created.

For instance, if you have this code:

Ascx Code

Then this macro will output the following lines to the output window:

Resulting output

Then all you have to do is copy the code to the codebehind file, change the inherit, and presto, a webcontrol.

The macro:

Sub GenerateWebcontrolCode()
    Dim str As String = ""
    Dim createCC As String = ""
    Dim renderCC As String = ""
    Dim attribsCC As String = ""
    Dim selection As TextSelection = DTE.ActiveDocument.Selection()
    selection.SelectAll()
    Dim theText As String = selection.Text

    'all <asp:Label like tags and id's
    Dim r As New Regex("\<(?<tag>\w*):(?<type>\w*)" & _
      "(.\n?)*?id=\""?(?<id>\w*)\""?(.\n?)*?>", RegexOptions.IgnoreCase)
    Dim matches As MatchCollection = r.Matches(theText)
    Dim m As Match

    'set the startindex to position after the last <%@ register tag!!
    Dim startindex As Integer = 0
    Dim matchRegistertags As Match = Regex.Match(theText, _
                     "<%@.*?>", RegexOptions.RightToLeft)
    startindex = matchRegistertags.Index + matchRegistertags.Length
    If (startindex < 0) Then
        startindex = 0
    End If

    For Each m In matches
        'only start again after endtag (templated controls will not work!!)
        If m.Index > startindex Then

            Dim tp As String = m.Groups("type").Value
            Dim id As String = m.Groups("id").Value
            Dim tag As String = m.Groups("tag").Value

            'the stuff for the render override
            'Get the html in before the control 
            'and write this to the HTMLwriter
            Dim htmlstr As String = _
              theText.Substring(startindex, m.Index - startindex)
            htmlstr = htmlstr.Replace("""", """""")
            renderCC += "writer.Write(@""" + htmlstr + """);" + vbCrLf
            renderCC += id + ".RenderControl(writer);" + vbCrLf

            'Set the index to the position of the endtag (if available, 
            'otherwise control is closed with />
            startindex = m.Index + m.Length
            Dim endtag As String = "</" + tag + ":" + tp + ">"
            Dim inext2 As Integer = theText.IndexOf(endtag, startindex)
            If inext2 <> -1 Then
                startindex = inext2 + endtag.Length
            End If

            ' the stuff for the init procedures make sure you add this to 
            createCC += id + " = new " + tp + "();" + vbCrLf

            'Add attributes to the object.
            'Only attibutes assigned within the first tag no 
            'templated controls or default properties are set
            Dim r2 As New Regex("(?<prop>\w*)=\""?(?<value>\w*)\""?", _
                                                RegexOptions.IgnoreCase)
            Dim ms2 As MatchCollection = r2.Matches(m.Value)
            Dim m2 As Match
            For Each m2 In ms2
                Dim prop As String = m2.Groups("prop").Value
                Dim val As String = m2.Groups("value").Value
                If prop.ToLower() <> "runat" Then
                    createCC += id + "." + prop + " = """ + val + """;" + vbCrLf
                End If
            Next

            'add the control to the control collection
            createCC += "this.Controls.Add(" + id + ");" + vbCrLf + vbCrLf
        End If

    Next

    'render the final html after the last control
    Dim htmlstr2 As String = theText.Substring(startindex, _
                                   theText.Length - startindex)
    htmlstr2.Replace("""", """""")
    renderCC += "writer.Write(@""" + htmlstr2 + """);" + vbCrLf
    'now show the text om the output window
    Dim win As Window = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutput)
    Dim OWp As OutputWindowPane = win.Object.OutputWindowPanes.Item(1)
    OWp.Clear()
    OWp.Activate()
    OWp.OutputString("-----------------" + vbCrLf)
    OWp.OutputString("Add this to the Init procedure" & _ 
                          " (before any events are assigned)" + vbCrLf)
    OWp.OutputString("TODO check type casing and property types," & _
                       " dynamically load templated elements" + vbCrLf)
    OWp.OutputString("-----------------" + vbCrLf)
    OWp.OutputString(createCC)
    OWp.OutputString("-----------------" + vbCrLf)
    OWp.OutputString("Add this to the render function" + vbCrLf)
    OWp.OutputString("-----------------" + vbCrLf)
    OWp.OutputString(renderCC)
    OWp.TextDocument.Selection.GotoLine(OWp.TextDocument.EndPoint().Line())
    DTE.ExecuteCommand("View.Output")
End Sub

Just copy paste the code into the .ascx.cs file and inherit from WebControl instead of UserControl. (Or if you want, create a new class file with both the code.)

Unfortunately, you'll have to check the casing of the types because if there is <asp:button in the ascx file, then the type will be button (lowercase), also check the type of the parameters assigned. (String type is assumed, see Button1.BorderWidth = "4px"; this should be just 4 of course.)

Well, good luck and hope this saves some typing.

Greetings Rooc.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Rooc

Web Developer

Netherlands Netherlands

Member

Developer since 1998 and mainly focused on web development. Currently employed as technical architect.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
QuestionHow to use this macro Pinmemberrikin8:06 7 Sep '10  
GeneralMore Details PinmemberRobert Collins12:40 7 Jun '07  
GeneralRe: More Details Pinmembershaktisanjeev4:09 13 Oct '09  
QuestionAny improvement ? Pinmemberakades22:15 8 Jun '06  
GeneralNice tool Pinmembernotbono6:11 4 Nov '04  
GeneralThe other way round Pinmemberterence wallace3:14 1 Sep '04  
GeneralRe: The other way round PinmemberRooc20:24 5 Sep '04  
GeneralRe: The other way round Pinmemberterence wallace5:07 6 Sep '04  
GeneralRe: The other way round PinmemberEric Newton10:03 6 Nov '04  
GeneralThis is great! Pinmemberworldspawn20:51 12 Aug '04  
GeneralRe: This is great! PinmemberRooc7:16 14 Aug '04  
GeneralRe: This is great! PinmemberEric Newton10:05 6 Nov '04  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web04 | 2.5.120517.1 | Last Updated 11 Aug 2004
Article Copyright 2004 by Rooc
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid