65.9K
CodeProject 正在变化。 阅读更多。
Home

将 Usercontrol 转换为 WebControl

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.08/5 (6投票s)

2004年8月11日

viewsIcon

72827

downloadIcon

614

你创建了一个具有 HTML 布局的漂亮的 UserControl,但希望将其用作服务器控件。此宏将为你生成实例化和渲染代码。

引言

你是否曾经编写了一个不错的 UserControl,并希望将其迁移到 WebControl?那么你就会知道你需要自己编写大量的渲染和初始化代码。使用此宏,这些代码将从你创建的 .ascx 文件中生成。

例如,如果你有以下代码

Ascx Code

那么此宏将在输出窗口中输出以下行

Resulting output

然后你只需要将代码复制到代码隐藏文件中,更改继承关系,瞧,一个 WebControl 就完成了。

该宏

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

只需将代码复制粘贴到 .ascx.cs 文件中,并从 WebControl 而不是 UserControl 继承。(或者,如果你愿意,可以创建一个新的类文件,其中包含所有代码。)

不幸的是,你必须检查类型的命名大小写,因为如果在 ascx 文件中存在 <asp:button,则类型将是 button(小写),还要检查分配的参数的类型。(假设 String 类型,参见 Button1.BorderWidth = "4px";当然,这应该只是 4。)

祝你好运,希望这能节省一些打字。

问候 Rooc。

© . All rights reserved.