Here are a few macros I wrote to generate property accessors from your class level variables.
These Macros are absolutely not an example of great coding. They are really pretty crappy, but they do the job, so as I kept tweaking them I never went back to clean up the code or look into more elegant ways to accomplish this stuff.
Some notes about these macros:
1) dasBlog’s code display tools somehow screws up the LFs, so if you cut and paste this code you might want to first paste it into Word, or WordPad.
2) These macros need some space between your last bit of code and the end of your class. In other words, the line directly above “End Class” can’t have code in it. Fixing this bug wouldn’t be a big deal but I haven’t done it yet.
3) These macros will allow formatting of your variables/accessors in any of the following ways:
private csClassLevelString as String '*** property name "ClassLevelString"
private mModuleLevelInt as Integer '*** property name "ModuleLevelInt"
private _SomeObject as Object '*** property name "SomeObject"
private camelCaseBoolean as Boolean '*** WON'T work: property will be named "CaseBoolean"
4) To use these macros, simply declare your class level (instance) variables. Then with your mouse, highlight the ones you want to create property accessors for. You need to highlight the entire definition from “private” to data type, and of course you can highlight a bunch at 1 time. i.e. I could highlight the entire code block above and it would produce 4 property accessors.
5) Again… this code… well it kinda sucks. So if you are looking for a lesson on producing good code, avert your eyes, but the output is good.
Imports System
Imports EnvDTE
Imports EnvDTE80
Imports System.Diagnostics
Public Module Module1
Public Sub AddClassProperties()
Call AddClassProperties(False)
End Sub
Public Sub AddCslaProperties()
Call AddClassProperties(True)
End Sub
‘ highlight the private properties
Private Sub AddClassProperties(ByVal useCsla As Boolean)
Dim oTextSelection As TextSelection = DTE.ActiveWindow.Selection
Dim iLinesSelected = oTextSelection.TextRanges.Count
Dim colPropertyList As New Collection()
Dim iIndex As Integer
Dim oStart As EditPoint = oTextSelection.TopPoint.CreateEditPoint()
Dim oEnd As TextPoint = oTextSelection.BottomPoint
‘Create an Undo context object so all the changes can be
‘undone by CTRL+Z
Dim oUnDo As UndoContext = DTE.UndoContext
‘Supress the User Interface. This will make it run faster
‘and make all the changes appear once
DTE.SuppressUI = True
Try
oUnDo.Open(“Comment Line”)
Dim sProperty As String
Dim sLineOfText As String
Do While (oStart.LessThan(oEnd))
sLineOfText = oStart.GetText(oStart.LineLength).Trim
‘*** do some kind of simple check to make sure that this line
‘*** isn’t blank and isn’t some other kind of code or comment
If (sLineOfText.IndexOf(” As “) >= 0 And ( _
(sLineOfText.IndexOf(“Public “) >= 0) Or _
(sLineOfText.IndexOf(“Private “) >= 0) Or _
(sLineOfText.IndexOf(“Dim “) >= 0) Or _
(sLineOfText.IndexOf(“Protected “) >= 0) Or _
(sLineOfText.IndexOf(“Friend “) >= 0) Or _
(sLineOfText.IndexOf(“ReDim “) >= 0) Or _
(sLineOfText.IndexOf(“Shared “) >= 0) Or _
(sLineOfText.IndexOf(“Static “) >= 0) _
)) Then
sProperty = oStart.GetText(oStart.LineLength).Trim.Replace(” New “, ” “).Replace(“()”, “”)
colPropertyList.Add(sProperty)
End If
oStart.LineDown()
oStart.StartOfLine()
Loop
If colPropertyList.Count > 0 Then
For Each sProperty In colPropertyList
Call InsertProperty(sProperty, useCsla)
Next
Else
MsgBox(“You must select the class properties”)
End If
Catch ex As System.Exception
Debug.WriteLine(ex)
If MsgBoxResult.Yes = MsgBox(“Error: “ & ex.ToString & vbCrLf & “Undo Changes?”, MsgBoxStyle.YesNo) Then
oUnDo.SetAborted()
End If
Return
Finally
‘If an error occured, then need to make sure that the undo context is cleaned up.
‘Otherwise, the editor can be left in a perpetual undo context
If oUnDo.IsOpen Then
oUnDo.Close()
End If
DTE.SuppressUI = False
End Try
End Sub
Private Sub InsertProperty(ByVal sProp As String, Optional ByVal UseCsla As Boolean = False)
Dim oTextSelection As TextSelection = DTE.ActiveWindow.Selection
Dim sMember As String = sProp.Substring(sProp.IndexOf(” “)).Trim
Dim sDataType As String
Dim sName As String
Dim i As Integer
Dim iAscVal As Integer
i = sMember.IndexOf(“(“)
If Not i = -1 Then
sMember = sMember.Substring(0, i)
End If
i = sMember.IndexOf(“=”)
If Not i = -1 Then
sMember = sMember.Substring(0, i)
End If
sDataType = sMember.Substring(sMember.IndexOf(” As “) + 1)
For i = 0 To sMember.Length – 1
‘iAscVal = Asc(Mid(sName, i, 1))
iAscVal = Asc(sMember.Chars(i))
If iAscVal > 64 And iAscVal < 91 Then
sName = sMember.Substring(i)
Exit For
End If
Next i
sName = sName.Substring(0, sName.IndexOf(” As “) + 1).Trim
If sName.Length = 0 Then
MsgBox(“Unable to process the class property: “ & sMember & “. This is usually caused by an incorrect naming convention (e.g. not cxName)”)
Return
End If
sMember = sMember.Substring(0, sMember.Length – sDataType.Length).Trim
With oTextSelection
Dim pt As TextPoint = .ActivePoint.CodeElement(vsCMElement.vsCMElementClass).GetEndPoint(vsCMPart.vsCMPartWhole)
If pt Is Nothing Then
pt = .ActivePoint.CodeElement(vsCMElement.vsCMElementStruct).GetEndPoint(vsCMPart.vsCMPartWhole)
End If
.MoveToPoint(pt)
.LineUp()
.EndOfLine()
.Text = “Public Property “ & sName & “() “ & sDataType
.NewLine()
If UseCsla Then
.Text = “CanReadProperty(True)”
.NewLine()
End If
.Text = “Return “ & sMember
.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText)
.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstColumn, True)
.Copy()
.LineDown(False, 3)
DTE.ExecuteCommand(“Edit.Paste”)
If UseCsla Then
.Text = “CanWriteProperty(True)”
.NewLine()
.Text = “If Me.” & sMember & ” <> Value then”
.NewLine()
End If
.Text = “Me.” & sMember & ” = Value”
If UseCsla Then
.NewLine()
.Text = “PropertyHasChanged()”
End If
.LineDown(False, 2)
If UseCsla Then
.LineDown(False, 1)
End If
.NewLine(2)
End With
End Sub
End Module