Click here to Skip to main content
15,887,485 members
Articles / Web Development / ASP.NET
Article

Convert a Usercontrol to a WebControl

Rate me:
Please Sign up or sign in to vote.
2.08/5 (6 votes)
10 Aug 2004 71.4K   614   30   12
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:

VB
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


Written By
Web Developer
Netherlands Netherlands
Developer since 1998 and mainly focused on web development. Currently employed as technical architect.

Comments and Discussions

 
QuestionHow to use this macro Pin
rikin7-Sep-10 8:06
rikin7-Sep-10 8:06 
GeneralMore Details Pin
Robert Collins7-Jun-07 12:40
Robert Collins7-Jun-07 12:40 
GeneralRe: More Details Pin
Shakti khurana13-Oct-09 4:09
Shakti khurana13-Oct-09 4:09 
QuestionAny improvement ? Pin
akades8-Jun-06 22:15
akades8-Jun-06 22:15 
GeneralNice tool Pin
notbono4-Nov-04 6:11
notbono4-Nov-04 6:11 
GeneralThe other way round Pin
Terence Wallace1-Sep-04 3:14
Terence Wallace1-Sep-04 3:14 
What if I need to change a webcontrol to a user control.
GeneralRe: The other way round Pin
Rooc5-Sep-04 20:24
Rooc5-Sep-04 20:24 
GeneralRe: The other way round Pin
Terence Wallace6-Sep-04 5:07
Terence Wallace6-Sep-04 5:07 
GeneralRe: The other way round Pin
Eric Newton6-Nov-04 10:03
Eric Newton6-Nov-04 10:03 
GeneralThis is great! Pin
worldspawn12-Aug-04 20:51
worldspawn12-Aug-04 20:51 
GeneralRe: This is great! Pin
Rooc14-Aug-04 7:16
Rooc14-Aug-04 7:16 
GeneralRe: This is great! Pin
Eric Newton6-Nov-04 10:05
Eric Newton6-Nov-04 10:05 

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.