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.


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

  1. Mike Smith says:

    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. Jaggy says:

    Big thanks. Works like a charm.

  3. Jose A. Ramirez says:

    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

  4. Duncan Smart says:

    @Jose: yes I think you are missing something. Namely the last point: “manually make the Form class partial”.

  5. Jose A. Ramirez says:

    Hi Duncan,
    it works perfectly now!
    Thanks much,
    Jose

  6. Alper says:

    Hi Duncan,

    Download link seems to be broken. Could you email macro code to me?

    Thanks,
    Alper

  7. Diana says:

    Great work! Save my life!

  8. lakshmipathy says:

    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

  9. Max says:

    Thanks a lot!
    Very useful tool!

  10. Adam Best says:

    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

  11. Guy says:

    Very nice. I don’t know why VS doesn’t do this automatically to clean things up!

    Thank you!

  12. David C says:

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

  13. Thanks a lot! Worked as “advertised” … ;)

  14. Jeff Shelby says:

    There’s a version for VB code here that also fixes a couple of bugs in this one.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <pre> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>