in

ASP.NET Weblogs

Andy Smith's Blog

Page.RegisterStartupScript('Andy', 'MetaBuilders_WebControls_GainKnowledge();');

Web Control Developer Macro Goodness

I've had these control dev macros sitting around for a while, and I thought I'd share them finally. First I looked for a wiki I could post them to, but I was surprised to not find one for vstudio addins/macros/whatnot. The closest I found was the gotdotnet developer powertoy site, but the whole submission/wait-for-approval thing just bores me. So, I decided to post the macro file here. I hope you find them useful:

Imports EnvDTE
Imports System
Imports System.Diagnostics
Imports System.IO
Imports System.Text

Public Module CodeGen

    ' Creates A Public Style Property
    ' Write the following line into the code area:
    ' <StyleType> <PropertyName>
    ' Select the text, run this macro
    Public Sub CreateStyleProperty()
        CheckLanguage()
        Dim ts As TextSelection = DTE.ActiveDocument.Selection
        Dim selection As String = ts.Text.Replace(vbTab, " ").Trim(" ")
        Dim words() As String = selection.Split(" ")
        If words.Length <> 2 Then
            Return
        End If
        Dim typeName As String = words(0)
        Dim propertyName As String = words(1)
        Dim memberName As String = "_" & propertyName.Substring(0, 1).ToLower() & propertyName.Substring(1)
        Dim code As New StringBuilder
        Dim codeWriter As New StringWriter(code)
        Try
            codeWriter.WriteLine("[")
            codeWriter.WriteLine("Category( ""Style"" ),")
            codeWriter.WriteLine("Description( """" ),")
            codeWriter.WriteLine("DefaultValue( null ),")
            codeWriter.WriteLine("DesignerSerializationVisibility(DesignerSerializationVisibility.Content),")
            codeWriter.WriteLine("PersistenceMode(PersistenceMode.InnerProperty),")
            codeWriter.WriteLine("]")
            codeWriter.WriteLine("public {0} {1} {{", typeName, propertyName)
            codeWriter.WriteLine("get {")
            codeWriter.WriteLine("if ( {0} == null ) {{", memberName)
            codeWriter.WriteLine("{0} = new {1}();", memberName, typeName)
            codeWriter.WriteLine("if ( IsTrackingViewState ) {")
            codeWriter.WriteLine("((IStateManager){0}).TrackViewState();", memberName)
            codeWriter.WriteLine("}")
            codeWriter.WriteLine("}")
            codeWriter.WriteLine("return {0};", memberName)
            codeWriter.WriteLine("}")
            codeWriter.WriteLine("}")
            codeWriter.WriteLine("private {0} {1};", typeName, memberName)
            codeWriter.Flush()
        Finally
            If Not codeWriter Is Nothing Then
                DirectCast(codeWriter, IDisposable).Dispose()
            End If
        End Try
        ReplaceCode(code.ToString(), "CreateStyleProperty" & propertyName)
    End Sub

    ' Creates a Public ITemplate Property
    ' Write the following line into the code area:
    ' <PropertyName> [<TemplateContainerType>]
    ' Select the text, run this macro
    Public Sub CreateTemplateProperty()
        CheckLanguage()
        Dim ts As TextSelection = DTE.ActiveDocument.Selection
        Dim selection As String = ts.Text.Replace(vbTab, " ").Trim(" ")
        Dim words() As String = selection.Split(" ")
        If 1 > words.Length OrElse words.Length > 2 Then
            Return
        End If
        Dim propertyName As String = words(0)
        Dim templateContainer As String = ""
        If words.Length = 2 Then
            templateContainer = words(1)
        End If
        Dim memberName As String = "_" & propertyName.Substring(0, 1).ToLower() & propertyName.Substring(1)
        Dim code As New StringBuilder
        Dim codeWriter As New StringWriter(code)
        Try
            codeWriter.WriteLine("[")
            codeWriter.WriteLine("Browsable( false ),")
            codeWriter.WriteLine("DefaultValue( null ),")
            codeWriter.WriteLine("Description( """" ),")
            codeWriter.WriteLine("PersistenceMode(PersistenceMode.InnerProperty),")
            If templateContainer <> "" Then
                codeWriter.WriteLine("TemplateContainer( typeof( {0} ) ),", templateContainer)
            End If
            codeWriter.WriteLine("]")
            codeWriter.WriteLine("public ITemplate {0} {{", propertyName)
            codeWriter.WriteLine("get {")
            codeWriter.WriteLine("return {0};", memberName)
            codeWriter.WriteLine("}")
            codeWriter.WriteLine("set {")
            codeWriter.WriteLine("{0} = value;", memberName)
            codeWriter.WriteLine("ChildControlsCreated = false;")
            codeWriter.WriteLine("}")
            codeWriter.WriteLine("}")
            codeWriter.WriteLine("private ITemplate {0};", memberName)
            codeWriter.Flush()
        Finally
            If Not codeWriter Is Nothing Then
                DirectCast(codeWriter, IDisposable).Dispose()
            End If
        End Try
        ReplaceCode(code.ToString(), "CreateStyleProperty" & propertyName)
    End Sub

    ' Creates A Public ViewState-Backed Property
    ' Write the following line into the code area:
    ' <PropertyType> <PropertyName> = <DefaultValue>;
    ' Select the text, run this macro
    Public Sub CreateViewStateProperty()
        CheckLanguage()

        Dim ts As TextSelection = DTE.ActiveDocument.Selection
        Dim selection As String = ts.Text.Replace(vbTab, " ").Trim(" ")
        Dim words() As String = selection.Split(" ")
        If words.Length < 3 Then
            Return
        End If

        Dim typeName As String
        Dim propertyName As String
        Dim defaultValue As String
        typeName = words(0)
        propertyName = words(1)
        defaultValue = selection.Substring(selection.IndexOf("=") + 2)
        defaultValue = defaultValue.Substring(0, defaultValue.Length - 1)
        Dim code As New StringBuilder
        Dim codeWriter As New StringWriter(code)
        Try
            codeWriter.WriteLine("[")
            codeWriter.WriteLine("Bindable(true),")
            codeWriter.WriteLine("Category( """" ),")
            codeWriter.WriteLine("Description( """" ),")
            codeWriter.WriteLine("DefaultValue( {0} ),", defaultValue)
            codeWriter.WriteLine("]")
            codeWriter.WriteLine("public virtual " & typeName & " " & propertyName & " {")
            codeWriter.WriteLine("get {")
            codeWriter.WriteLine("Object state = ViewState[""{0}""];", propertyName)
            codeWriter.WriteLine("if ( state != null ) {")
            codeWriter.WriteLine("return ({0})state;", typeName)
            codeWriter.WriteLine("}")
            codeWriter.WriteLine("return {0};", defaultValue)
            codeWriter.WriteLine("}")
            codeWriter.WriteLine("set {")
            codeWriter.WriteLine("ViewState[""{0}""] = value;", propertyName)
            codeWriter.WriteLine("}")
            codeWriter.WriteLine("}")
            codeWriter.Flush()
        Finally
            If Not codeWriter Is Nothing Then
                DirectCast(codeWriter, IDisposable).Dispose()
            End If
        End Try
        ReplaceCode(code.ToString(), "CreateViewStateProperty" & propertyName)
    End Sub

    ' Creates A Public Event and Protected OnEvent Method
    ' Write the following line into the code area:
    ' <EventName> [<DelegateType> <EventArgsType>]
    ' Select the text, run this macro
    Public Sub CreateEvent()
        CheckLanguage()
        Dim ts As TextSelection = DTE.ActiveDocument.Selection
        Dim selection As String = ts.Text.Replace(vbTab, " ").Trim(" ")
        Dim words() As String = selection.Split(" ")
        If words.Length <> 1 AndAlso words.Length <> 3 Then
            Return
        End If
        Dim eventName As String = words(0)
        Dim delegateTypeName As String = "EventHandler"
        Dim eventArgsTypeName As String = "EventArgs"
        If words.Length = 3 Then
            delegateTypeName = words(1)
            eventArgsTypeName = words(2)
        End If

        Dim raiserName As String = "On" & eventName
        Dim eventObjectName As String = "event" & eventName
        Dim code As New StringBuilder
        Dim codeWriter As New StringWriter(code)
        Try
            codeWriter.WriteLine("#region {0} Event", eventName)
            codeWriter.WriteLine()
            codeWriter.WriteLine("public event {0} {1} {{", delegateTypeName, eventName)
            codeWriter.WriteLine("add {")
            codeWriter.WriteLine("Events.AddHandler( {0}, value );", eventObjectName)
            codeWriter.WriteLine("}")
            codeWriter.WriteLine("remove {")
            codeWriter.WriteLine("Events.RemoveHandler( {0}, value );", eventObjectName)
            codeWriter.WriteLine("}")
            codeWriter.WriteLine("}")
            codeWriter.WriteLine()
            codeWriter.WriteLine("protected void {0}( {1} e ) {{", raiserName, eventArgsTypeName)
            codeWriter.WriteLine("{0} handler = Events[ {1} ] as {0};", delegateTypeName, eventObjectName)
            codeWriter.WriteLine("if ( handler != null ) {")
            codeWriter.WriteLine("handler( this, e );")
            codeWriter.WriteLine("}")
            codeWriter.WriteLine("}")
            codeWriter.WriteLine()
            codeWriter.WriteLine("private static readonly Object {0} = new Object();", eventObjectName)
            codeWriter.WriteLine()
            codeWriter.WriteLine("#endregion")
            codeWriter.Flush()
        Finally
            If Not codeWriter Is Nothing Then
                DirectCast(codeWriter, IDisposable).Dispose()
            End If
        End Try
        ReplaceCode(code.ToString(), "CreateEvent" & eventName)
    End Sub

    ' Surrounds the selected code with a try/catch/finally block
    Public Sub InsertTryCatchFinally()
        Dim endCode As New StringBuilder
        Dim writer As New StringWriter(endCode)
        Try
            writer.WriteLine("")
            writer.WriteLine("} catch( Exception ex ) {")
            writer.WriteLine("")
            writer.WriteLine("} finally {")
            writer.WriteLine("")
            writer.WriteLine("}")
            writer.Flush()
        Finally
            If Not writer Is Nothing Then
                DirectCast(writer, IDisposable).Dispose()
            End If
        End Try
        SurroundSelectionWithCode("try {" & Environment.NewLine, endCode.ToString(), "InsertTryCatchFinally")
    End Sub

    ' Replaces the selected code with the given new code
    Private Sub ReplaceCode(ByVal newCode As String, ByVal undoContextName As String)
        Dim selection As TextSelection = DTE.ActiveDocument.Selection
        Dim undoContextOpened As Boolean = False
        Try
            If Not DTE.UndoContext.IsOpen Then
                Call DTE.UndoContext.Open(undoContextName, False)
                undoContextOpened = True
            End If
            ' Replace the text and SmartFormat it
            selection.Delete()
            selection.Insert(newCode, vsInsertFlags.vsInsertFlagsInsertAtStart)
            selection.TopPoint.CreateEditPoint.SmartFormat(selection.BottomPoint)
        Catch ex As Exception
            MsgBox("Unable To Perform Code Alteration:" & Environment.NewLine & ex.Message, MsgBoxStyle.OKOnly, "Problem Running Macro")
        Finally
            If undoContextOpened Then
                Call DTE.UndoContext.Close()
            End If
        End Try
    End Sub

    ' Surrounds the selected code with the given prefix and suffix code
    Private Sub SurroundSelectionWithCode(ByVal startCode As String, ByVal endCode As String, ByVal undoContextName As String)
        Dim selection As TextSelection = DTE.ActiveDocument.Selection
        Dim undoContextOpened As Boolean = False
        Try
            If Not DTE.UndoContext.IsOpen Then
                Call DTE.UndoContext.Open(undoContextName, False)
                undoContextOpened = True
            End If
            Dim tp As EditPoint = selection.TopPoint.CreateEditPoint()
            selection.TopPoint.CreateEditPoint().Insert(startCode)
            Dim bp As EditPoint = selection.BottomPoint.CreateEditPoint()
            bp.Insert(endCode)
            tp.SmartFormat(bp)
        Catch ex As Exception
            MsgBox("Unable To Perform Code Alteration:" & Environment.NewLine & ex.Message, MsgBoxStyle.OKOnly, "Problem Running Macro")
        Finally
            If undoContextOpened Then
                Call DTE.UndoContext.Close()
            End If
        End Try
    End Sub

    ' Ensures that the macro is modifying only c# documents
    Private Sub CheckLanguage()
        If DTE.ActiveDocument.Language <> "CSharp" Then
            Throw New System.Exception("This Macro only works on C# code")
        End If
    End Sub
End Module

Comments

 

Kevin Tunis said:

Andy, in your post you said you were looking for a wiki to post your macros to. I have posted this at http://dotnetdevelopercenter.com/default.aspx/MyWiki.VisualStudioAddIns with a reference back to your blog and invite you to make changes, add new vstudio addins, macros and whatnot.
August 11, 2004 6:20 PM

Leave a Comment

(required)  
(optional)
(required)  
Add