Click here to Skip to main content
Licence CPOL
First Posted 23 Dec 2009
Views 10,679
Downloads 141
Bookmarked 14 times

Add-ins for Generating Properties from Class Variables in Visual Studio .NET

By Sebastien Termote | 5 Aug 2010
Add-in Visual Studio 2008 for automatically generating properties (Getter and Setter)

1
3 votes, 33.3%
2

3
2 votes, 22.2%
4
4 votes, 44.4%
5
2.89/5 - 9 votes
μ 2.89, σa 2.46 [?]
Before

Before

After

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;
}

/// <summary>
/// Retrieve all 'class' and 'struct' in the active document
/// </summary>
/// <param name="elem"></param>
/// <param name="rootName"></param>
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 null, create a new property else modify
    if (field.Property == null)
    {
        property = this.m_currentStructure.AddProperty
		(field, createGet, createSet, position);
        //Create summary
        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

  • 22/12/2009 - Version 1.0

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Sebastien Termote

Software Developer

France France

Member


Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralMy vote of 5 PinmemberHeywood7:33 3 Aug '10  
GeneralRe: My vote of 5 PinmemberSebastien Termote8:13 3 Aug '10  
GeneralMy vote of 5 PinsupporterPaul Selormey5:55 3 Aug '10  
GeneralRe: My vote of 5 PinmemberSebastien Termote6:00 3 Aug '10  
QuestionZIp file empty ? Pinmemberbsran11:52 4 Jun '10  
AnswerRe: ZIp file empty ? PinmemberSebastien Termote0:32 3 Aug '10  
GeneralMy vote of 2 PinmemberBob Geiger6:12 24 Dec '09  
General[My vote of 2] As someone already said, you should use Snippets PinmvpSacha Barber23:25 23 Dec '09  
GeneralRe: [My vote of 2] As someone already said, you should use Snippets PinmemberSebastien Termote23:50 3 Jan '10  
GeneralMy vote of 2 PinmemberGiga777:05 23 Dec '09  
GeneralRe: My vote of 2 PinsupporterPaul Selormey5:47 3 Aug '10  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web04 | 2.5.120209.1 | Last Updated 5 Aug 2010
Article Copyright 2009 by Sebastien Termote
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid