Converting Visual Studio 2003 WinForms to Visual Studio 2005/2008 partial classes

.NET 2.0 introduced partial classes which enables “.designer” files in Visual Studio 2005 and later. That is, all of the visual designer-generated code (control declarations, the InitializeComponent method, etc) can be kept in a file separate from your regular code. When you open up a .NET 1.x Visual Studio 2003 WinForms project up in Visual Studio 2005/2008 it will upgrade your project to .NET 2.0 just fine, but unfortunately it doesn’t migrate your WinForms classes over to the new “.designer” project structure.

Initially I thought this would be a job for a DXCore plug-in (the free framework upon which CodeRush is built) as it provides plug-ins with an object model of the code which could be used to grab all the right members and move them over into a designer file. Before I looked into this though I checked what the options were for simply implementing it as a Visual Studio Macro. I was fully expecting to have to use a regular expression to grep the code file to perform the task, but was pleasantly surprised to find that the Visual Studio extensibility API in available to macros provides a code model (based on the .NET CodeDom I presume) which you can traverse to inspect and manipulate the underlying code.

So, here’s what the resulting “ExtractWinFormsDesignerFile” macro does:

  • Locates the first class in the selected project item (DTE.SelectedItems.Item(1).ProjectItem) by traversing the ProjectItem.FileCodeModel.CodeElements
  • Extracts the InitializeComponent and Dispose methods from the class by traversing CodeClass.Members
  • Extracts all control fields: that is, all fields whose type derives from System.Windows.Forms.Control or System.ComponentModel.Container or whose type name starts with System.Windows.Forms
  • Puts all the extracted code into  a new “FormName.Designer.cs” file.

This is currently C# only – it could easily be converted to generated VB.NET code or adapted use the FileCodeModel properly and perhaps create the code in an language-agnostic way when generating the designer file. I took a shortcut in just generating the designer file as a string and writing it directly to a file.

To “install”: download the macro text and copy the methods into a Visual Studio Macro Module (use ALT+F11 to show the Macro editor).

To use:

  • Select a Windows Form in the Solution Explorer
  • Run the macro by showing the Macro Explorer (ALT+F8) and double-clicking the ‘ExtractWinFormsDesignerFile’ macro. (Obviously you can hook the macro up to a toolbar button if you like.)
  • You will then be prompted to manually make the Form class partial (another bit I was too lazy to work out how to get the macro to do): i.e. change
    public class MyForm : Form
    to
    public partial class MyForm : Form

Please leave a comment if this helps you.

23 thoughts on “Converting Visual Studio 2003 WinForms to Visual Studio 2005/2008 partial classes

  1. Hi Duncan
    I came across your blog today and have just converted a project with over 100 forms to partial classes using your macro.
    Thanks a lot for saving me a lot of work.

    Mike Smith

  2. I run the macro and it creates the designer class but the form in designer mode shows no controls just a blank grey form..

    Please let me know if I am missing something.

    Thanks,
    Jose A. Ramirez

  3. Thank you. you save a lot of time. i want to generate a boiler plate template so i used your code for getting the namespace and class name. thank you

  4. Hey man,

    Awesome macro, really helped me out a lot!

    I made a few enhancements, like only creating the designer if one doesn’t exist already, and automatically making the original class partial…

    Sub ExtractWinFormsDesignerFile()


    Dim newItemPath As String = dir & “\” & bareName & “.Designer.cs”

    ‘Check if designer file already exists
    ‘If it does, don’t create one — Adam Best
    Dim childItems As ProjectItems = item.ProjectItems
    Dim childItem As ProjectItem
    Dim designer As Boolean = False

    For Each childItem In childItems
    If (childItem.FileNames(1) = newItemPath) Then
    designer = True
    Exit For
    End If
    Next

    If (Not designer) Then
    Dim codeClass As CodeClass = findClass(item.FileCodeModel.CodeElements)


    makeOriginalClassPartial(item.FileCodeModel.CodeElements)

    End If
    End Sub

    And the added function is…

    ‘Make original class partial — Adam Best
    Function makeOriginalClassPartial(ByVal items As System.Collections.IEnumerable)

    Dim text As String = String.Empty
    Dim newText As String = String.Empty

    For Each codeEl As CodeElement In items
    If codeEl.Kind = vsCMElement.vsCMElementClass Then
    Dim start As EditPoint = codeEl.GetStartPoint().CreateEditPoint()
    Dim endPoint As TextPoint = codeEl.GetStartPoint(vsCMPart.vsCMPartBody)
    text = start.GetText(endPoint)
    If (Not text.Contains(“partial class”)) Then
    newText = text.Replace(“class”, “partial class”)
    start.Delete(endPoint)
    start.Insert(newText)
    End If
    ElseIf codeEl.Children.Count > 0 Then
    Dim partialOrigClass As Boolean = makeOriginalClassPartial(codeEl.Children)
    End If
    Next

    End Function

  5. Thank you so much! Not only does it work for windows forms, but also third party tools such as Datadynamics’ Active Reports.

  6. i have a win forms application developed in VS 2003, I have converted it to VS 2005 . after conversion we are having problems with some of the win forms, when i try open the design of win forms i see all html code. i tried doing like what you mentioned here but i m getting error on this line of macros code : “Dim namespaceName As String = codeClass.Namespace.FullName ” and the error message i get is “object reference not set to an instance of an object”….please help me if i m doing something wrong.

    1. The error suggests that there no namespace in the file – perhaps that the issue? You may need to adapt it to get it to work for you – it’s pretty straightforward code.

    1. i think u can bring macro back into vs 2019 if u add it as Extension from ‘manage Extensions’ screen, search for macro

Leave a comment