ramlicious Blogs by Tina & Prabhu

November 23, 2011

Creating Custom Code Snippets in Visual Studio

Filed under: .NET,C#,Programming,Visual Studio,XML — Prabhuram @ 7:12 pm

Definitely Visual Studio Code Snippets save a lot of development time. It makes magic by replacing a small code snippet with a code block. Say for example, by simply typing ctor and pressing tab generates a default constructor code for you. In this article I will show how easy it is to add a custom code snippet. Before creating one, we will study an existing code snippet that you already have. You can view the list of code snippets by opening Visual Studio and opening Code Snippet Manager… in the Tools menu. You can see the code snippet called ctor listed under Visual C#. Simply copy the location of the .snippet file from the window and open the XML snippet file in Notepad.

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets  xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
	<CodeSnippet Format="1.0.0">
		<Header>
			<Title>ctor</Title>
			<Shortcut>ctor</Shortcut>
			<Description>Code snippet for constructor</Description>
			<Author>Microsoft Corporation</Author>
			<SnippetTypes>
				<SnippetType>Expansion</SnippetType>
			</SnippetTypes>
		</Header>
		<Snippet>
			<Declarations>
				<Literal Editable="false">
					<ID>classname</ID>
					<ToolTip>Class name</ToolTip>
					<Function>ClassName()</Function>
					<Default>ClassNamePlaceholder</Default>
				</Literal>
			</Declarations>
			<Code Language="csharp"><![CDATA[public $classname$ ()
	{
		$end$
	}]]>
			</Code>
		</Snippet>
	</CodeSnippet>
</CodeSnippets>

The three parts that the learner should be interested in are:

  • Header, that informs about the shortcut key and the author
  • Literal Declarations, list of literals that are part of the snippet. You can think of the literals that appear when you use the prop (property) code snippet that requests for changes to the property name or simply as seen in this example it executes a Function to get the value.
  • Code, which is the information about the language and the code that the snippet will be expanded to (also note the SnippetType in Header)
Now you can create endless number of snippets with your imagination. I have created one for the sake of the reader. This code snippet creates a typed DataTable that is created from scratch. So this DataTable can be created by the developer without the use of Schema. All that the developer has to do is to add changes to the TODO part of the code.
<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">

    <Header>
      <Title>Typed DataTable</Title>
      <Shortcut>tdt</Shortcut>
      <Description>Code snippet for generating Typed DataTable</Description>
      <Author>Prabhuram Venkatesan</Author>
      <SnippetTypes>
        <SnippetType>Expansion</SnippetType>
      </SnippetTypes>
    </Header>
    <Snippet>
      <Declarations>
        <Literal>
          <ID>ObjectName</ID>
          <ToolTip>Prefix to the Class Name</ToolTip>
          <Default>Class</Default>
        </Literal>
        <Literal>
          <ID>DBColumn1</ID>
          <ToolTip>Column Name in the Database/T-SQL Query</ToolTip>
          <Default>db_column_1</Default>
        </Literal>
        <Literal>
          <ID>RowColumn1</ID>
          <ToolTip>DataRow property name for db_column_1</ToolTip>
          <Default>RowColumn1</Default>
        </Literal>
      </Declarations>
      <Code Language="csharp">
        <![CDATA[
using System.Data;

//Auto-generated code for Typed DataTable
public class $ObjectName$Table : DataTable
{
  public $ObjectName$Table()
    :base()
  {
    //TODO: Add all the remaining DB columns names
    Columns.Add(new DataColumn("$DBColumn1$", typeof(string)));
  }
  protected override Type GetRowType()
  {
    return typeof($ObjectName$Row);
  }

  protected override DataRow NewRowFromBuilder(DataRowBuilder builder)
  {
    return new $ObjectName$Row(builder);
  }
  public $ObjectName$Row this[int idx]
  {
    get { return ($ObjectName$Row)Rows[idx]; }
  }

  public void Add($ObjectName$Row row)
  {
    Rows.Add(row);
  }
  public new $ObjectName$Row NewRow()
  {
    $ObjectName$Row row = ($ObjectName$Row)NewRow();
    return row;
  }
}
public class $ObjectName$Row : DataRow
{
  internal $ObjectName$Row(DataRowBuilder builder)
    : base(builder)
  {
    //TODO: Assign default values to all the properties
    $RowColumn1$=String.Empty;
  }

  //TODO: Add all the columns you want as part of a Row
  //      Map the DB column name to a property
  public string $RowColumn1${
    get {return (string)base["$DBColumn1$"];}
    set {base["$DBColumn1$"]=value;}
  }
}
        ]]>
      </Code>
    </Snippet>

  </CodeSnippet>
</CodeSnippets>

And now with this, typing tdt and Tab will generate the following code for you.


using System.Data;

//Auto-generated code for Typed DataTable
public class RoleTable : DataTable
{
    public RoleTable()
        : base()
    {
        //TODO: Add all the remaining DB columns names
        Columns.Add(new DataColumn("db_column_1", typeof(string)));
    }
    protected override Type GetRowType()
    {
        return typeof(RoleRow);
    }

    protected override DataRow NewRowFromBuilder(DataRowBuilder builder)
    {
        return new RoleRow(builder);
    }
    public RoleRow this[int idx]
    {
        get { return (RoleRow)Rows[idx]; }
    }

    public void Add(RoleRow row)
    {
        Rows.Add(row);
    }
    public new RoleRow NewRow()
    {
        RoleRow row = (RoleRow)NewRow();
        return row;
    }
}
public class RoleRow : DataRow
{
    internal RoleRow(DataRowBuilder builder)
        : base(builder)
    {
        //TODO: Assign default values to all the properties
        RowColumn1 = String.Empty;
    }

    //TODO: Add all the columns you want as part of a Row
    //      Map the DB column name to a property
    public string RowColumn1
    {
        get { return (string)base["db_column_1"]; }
        set { base["db_column_1"] = value; }
    }
}

No Comments

No comments yet.

RSS feed for comments on this post.

Sorry, the comment form is closed at this time.

Powered by WordPress