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
|