将我的Visual Studio 2003项目迁移到VS2005(或VS2008)后,我的表单仍然位于单个文件中。
VS2005和VS2008上的新表单是使用部分类创建的,其中由编辑器生成的所有代码都保存在Designer.cs文件中。
由于VS2005表单创建是处理表单的一种更好的方法,因此我想知道是否存在一种将所有旧的单文件表单转换为VS2005局部类方法的方法。
我已经手工完成了一些操作,但这非常棘手,可能会导致一些严重的错误。
有什么建议么? PS:我正在使用Microsoft Visual C#2008 Express Edition。
最佳答案
这似乎是您想要的。
Converting Visual Studio 2003 WinForms to Visual Studio 2005/2008 partial classes :
' -------------------------------------------------------------------------
' Extract WinForms Designer File Visual Studio 2005/2008 Macro
' -------------------------------------------------------------------------
' Extracts the InitializeComponent() and Dispose() methods and control
' field delarations from a .NET 1.x VS 2003 project into a VS 2005/8
' style .NET 2.0 partial class in a *.Designer.cs file. (Currently C#
' only)
'
' To use:
' * Copy the methods below into a Visual Studio Macro Module (use
' ALT+F11 to show the Macro editor)
' * Select a Windows Form in the Solution Explorer
' * Run the macro by showing the Macro Explorer (ALT+F8) and double
' clicking the 'ExtractWinFormsDesignerFile' macro.
' * You will then be prompted to manually make the Form class partial:
' i.e. change "public class MyForm : Form"
' to
' "public partial class MyForm : Form"
'
' Duncan Smart, InfoBasis, 2007
' -------------------------------------------------------------------------
Sub ExtractWinFormsDesignerFile()
Dim item As ProjectItem = DTE.SelectedItems.Item(1).ProjectItem
Dim fileName As String = item.FileNames(1)
Dim dir As String = System.IO.Path.GetDirectoryName(fileName)
Dim bareName As String = System.IO.Path.GetFileNameWithoutExtension(fileName)
Dim newItemPath As String = dir & "\" & bareName & ".Designer.cs"
Dim codeClass As CodeClass = findClass(item.FileCodeModel.CodeElements)
Dim namespaceName As String = codeClass.Namespace.FullName
On Error Resume Next ' Forgive me :-)
Dim initComponentText As String = extractMember(codeClass.Members.Item("InitializeComponent"))
Dim disposeText As String = extractMember(codeClass.Members.Item("Dispose"))
Dim fieldDecls As String = extractWinFormsFields(codeClass)
On Error GoTo 0
System.IO.File.WriteAllText(newItemPath, "" _
& "using System;" & vbCrLf _
& "using System.Windows.Forms;" & vbCrLf _
& "using System.Drawing;" & vbCrLf _
& "using System.ComponentModel;" & vbCrLf _
& "using System.Collections;" & vbCrLf _
& "" & vbCrLf _
& "namespace " & namespaceName & vbCrLf _
& "{" & vbCrLf _
& " public partial class " & codeClass.Name & vbCrLf _
& " {" & vbCrLf _
& " #region Windows Form Designer generated code" & vbCrLf _
& " " & fieldDecls & vbCrLf _
& " " & initComponentText & vbCrLf _
& " #endregion" & vbCrLf & vbCrLf _
& " " & disposeText & vbCrLf _
& " }" & vbCrLf _
& "}" & vbCrLf _
)
Dim newProjItem As ProjectItem = item.ProjectItems.AddFromFile(newItemPath)
On Error Resume Next
newProjItem.Open()
DTE.ExecuteCommand("Edit.FormatDocument")
On Error GoTo 0
MsgBox("TODO: change your class from:" + vbCrLf + _
" ""public class " + codeClass.FullName + " : Form""" + vbCrLf + _
"to:" + _
" ""public partial class " + codeClass.FullName + " : Form""")
End Sub
Function findClass(ByVal items As System.Collections.IEnumerable) As CodeClass
For Each codeEl As CodeElement In items
If codeEl.Kind = vsCMElement.vsCMElementClass Then
Return codeEl
ElseIf codeEl.Children.Count > 0 Then
Dim cls As CodeClass = findClass(codeEl.Children)
If cls IsNot Nothing Then
Return findClass(codeEl.Children)
End If
End If
Next
Return Nothing
End Function
Function extractWinFormsFields(ByVal codeClass As CodeClass) As String
Dim fieldsCode As New System.Text.StringBuilder
For Each member As CodeElement In codeClass.Members
If member.Kind = vsCMElement.vsCMElementVariable Then
Dim field As CodeVariable = member
If field.Type.TypeKind <> vsCMTypeRef.vsCMTypeRefArray Then
Dim fieldType As CodeType = field.Type.CodeType
Dim isControl As Boolean = fieldType.Namespace.FullName.StartsWith("System.Windows.Forms") _
OrElse fieldType.IsDerivedFrom("System.Windows.Forms.Control") _
OrElse fieldType.IsDerivedFrom("System.ComponentModel.Container")
If isControl Then
fieldsCode.AppendLine(extractMember(field))
End If
End If
End If
Next
Return fieldsCode.ToString()
End Function
Function extractMember(ByVal memberElement As CodeElement) As String
Dim memberStart As EditPoint = memberElement.GetStartPoint().CreateEditPoint()
Dim memberText As String = String.Empty
memberText += memberStart.GetText(memberElement.GetEndPoint())
memberStart.Delete(memberElement.GetEndPoint())
Return memberText
End Function