Before
After
Introduction
In Visual Studio (VS), you must type property or generate it one by one. It's tedious if you have a lot of variables. This properties generator manages the properties creation and modification. So if you have ten variables with a snippet, you must call it ten times. With the properties generator, in one time, all variables of your choice are generated.
Background
In this article, I suppose than you know the base for developing add-ins. You can read this article if you do not know this base.
Using the Code
For using, the *.AddIn and the *.dll must be present in My Documents\Visual Studio 2008\Addins:
- ClassField.cs is a little class created for content information on variable and property of this variable.
- ClassManager.cs used for retrieve class, variable and write property.
ClassStruct
contains the interface Istruct,
this interface encapsulates CodeClass
and CodeStruct
. CodeClass
is a VS object which contains information on Class
and CodeStruct
information on Struct
.
ClassManager
The constructor of this class takes a DTE2
, it is an object of Visual Studio. With this object, we can retrieve in the active document all code elements (Namespace
, Class
, ...). For this, we use two methods, ProcessElement
and LoadClass
.
ProcessElement(CodeElement elem)
is a recursive method used for finding Class
or Struct
present in the active document. We can know the type of the element with this property kind. Class
or Struct
found are stocked in m_Classes
. It is used for binding the combobox
with all class names. When the combobox
is changed, we call the method LoadClass(IStruct mclass)
.
LoadClass(Istruct mclass)
retrieves variable and properties present in mclass
and this bases. This method returns a list of ClassField
used for creating the treeview
.
private bool LoadClasses()
{
m_Classes = new List<IStruct>();
if (((this.m_applicationObject.ActiveDocument == null) ||
(this.m_applicationObject.ActiveDocument.ProjectItem == null)) ||
((this.m_applicationObject.ActiveDocument.ProjectItem.FileCodeModel == null) ||
(this.m_applicationObject.ActiveDocument.ProjectItem.FileCodeModel.CodeElements
== null)))
{
return false;
}
else
{
foreach (CodeElement element in
this.m_applicationObject.ActiveDocument.ProjectItem.FileCodeModel.CodeElements)
{
this.ProcessElement(element);
}
}
return true;
}
private void ProcessElement(CodeElement elem)
{
if (elem.Kind == vsCMElement.vsCMElementNamespace)
{
CodeNamespace namespac = elem as CodeNamespace;
foreach (CodeElement element in namespac.Members)
{
this.ProcessElement(element);
}
}
else if (elem.Kind == vsCMElement.vsCMElementClass)
{
ClassStructure item = new ClassStructure(elem as CodeClass);
this.m_Classes.Add(item);
foreach (CodeElement element2 in item.Members)
{
this.ProcessElement(element2);
}
}
else if (elem.Kind == vsCMElement.vsCMElementStruct)
{
StructStructure struct3 = new StructStructure(elem as CodeStruct);
this.m_Classes.Add(struct3);
}
}
For writing or remove a property, we use EditPoint
which is a VS object for manipulating the text. But before if the property does not exist, we create it with a call to m_currentStructure.AddProperty
. m_currentStructure
is the current Istruct
. AddProperty
method creates a new property code construct and inserts the code in the correct location. For the location, if it is a CodeElement
the property is created after it, 0
creates the new element at the beginning and -1
at the end. But this property is empty, we retrieve the start point of the property (get
or set
) and the end and deleted this selection point.Delete(point2);
after the delete of the empty property, we write our property point.Insert(field.GetMethod)
. If a property already exists, we insert a new line and write the property (get
or set
) we want.
For deleting a property, we select the start point and the end of the property, after we delete the selection:
public void WriteProperty(ClassField field, bool createGet,
bool createSet,bool setIsInternal, object position)
{
CodeProperty property;
if (field.Property == null)
{
property = this.m_currentStructure.AddProperty
(field, createGet, createSet, position);
EditPoint pt = property.StartPoint.CreateEditPoint();
pt.LineUp(1);
pt.Insert(string.Format(@"
/// <summary>
/// {0}{1}{2}
/// </summary>",
createGet ? "Gets" : string.Empty,
createSet && createGet ? "/" : string.Empty,
createSet ? "Sets" : string.Empty));
if (createGet)
{
property.Getter.IsShared = field.Field.IsShared;
EditPoint point = property.Getter.StartPoint.CreateEditPoint();
EditPoint point2 = property.Getter.EndPoint.CreateEditPoint();
point.Delete(point2);
point.Insert(field.GetMethod);
}
if (createSet)
{
property.Setter.IsShared = field.Field.IsShared;
EditPoint point = property.Setter.StartPoint.CreateEditPoint();
EditPoint point2 = property.Setter.EndPoint.CreateEditPoint();
point.Delete(point2);
point.Insert(field.SetMethod(setIsInternal));
}
}
else
{
property = field.Property;
if (createGet)
{
EditPoint point = property.Getter.EndPoint.CreateEditPoint();
point.Insert(Environment.NewLine);
point.Insert(field.GetMethod);
EditPoint point2 = property.StartPoint.CreateEditPoint();
EditPoint point3 = property.EndPoint.CreateEditPoint();
point2.SmartFormat(point3);
}
if (createSet)
{
EditPoint point = property.Getter.EndPoint.CreateEditPoint();
point.Insert(Environment.NewLine);
point.Insert(field.SetMethod(setIsInternal) );
EditPoint point2 = property.StartPoint.CreateEditPoint();
EditPoint point3 = property.EndPoint.CreateEditPoint();
point2.SmartFormat(point3);
}
}
}
class ClassField
{
public string GetMethod
{
get
{
return string.Format("get {{ return {0}{1}; }}",
this.m_Field.IsShared ? "" : "this.", this.m_Field.Name);
}
}
public string SetMethod(bool isInternal)
{
return string.Format("{2} set {{ {0}{1} = value; }}",
this.m_Field.IsShared ? "" : "this.", this.m_Field.Name, isInternal ?
"internal" : string.Empty );
}
}
History