Visual Studio 2008 插件复制并重命名表单文件,尽管重命名但仍出现重复成员错误
我在 Visual Studio 2008 中有一个 VB.NET 项目,我为其创建了一个专门的插件。该插件提示用户选择一个数据库表,获取模板表单类的文件,将它们复制到项目内的另一个目录,并在复制的文件中重命名表单类。然后,它打开新表单并根据数据库表中的字段向其中添加控件。
复制模板表单会导致后台编译器给出“重复成员”错误,例如“Private Sub InitializeComponents(...) 具有具有相同签名的多个定义”,即使我重命名了新表单和类的文件其中的名字。有时,这些错误在打开新表单之前就会消失,但当它们持续存在时,新表单无法正确打开,而是会引发错误。
我实现了一些代码,等待错误列表中的错误为零,然后再尝试打开新表单。这有时会有所帮助,但由于某种原因,有时错误根本不会消失,直到插件关闭为止。
我希望有人能够提供有关如何复制模板表单并重命名副本的提示,而后台编译器不会注意到重复的成员。如果那不可能,那么也许有人有替代方案?
这是我的代码,用于复制并重命名模板表单:
Private Sub CreateDataForm(ByVal tableName As String, ByVal displayName As String) ', ByVal subDataForms As IList(Of Object))
Try
Dim dataFormClassName As String = "frm" & MakeValidName(displayName)
Dim dataFormFileName As String = dataFormClassName & cVBSuffix
Dim templateFileName As String = DataFormTemplate.Name
Dim templateClassName As String = Replace(templateFileName, cVBSuffix, String.Empty)
'copy form template to data forms folder
'copy files associated with main projectitem
Dim newPItem As ProjectItem = Nothing
For i As Integer = 1 To DataFormTemplate.FileCount
newPItem = DataFormsFolder.ProjectItems.AddFromFileCopy(DataFormTemplate.FileNames(CShort(i)))
Next
'copy files associated with sub projectitems
For Each item As ProjectItem In DataFormTemplate.ProjectItems
For i As Integer = 1 To item.FileCount
DataFormsFolder.ProjectItems.AddFromFileCopy(item.FileNames(CShort(i)))
Next
Next
newPItem.Name = dataFormFileName
newPItem.ContainingProject.Save()
'fix class name for dataform template
FixDataFormClassName(DataFormTemplate, dataFormClassName, templateClassName)
newPItem.ContainingProject.Save()
Application.DoEvents()
'get table metadata
Dim lGetColumnInfo As DataColumnCollection = GetColumnInfo(tableName)
'add field controls
ConvertColumnInfoToFormControls(newPItem, lGetColumnInfo, tableName, displayName)
Catch ex As Exception
DisplayExceptionMessage(ex)
End Try
End Sub
Private Shared Sub FixDataFormClassName(ByVal pItem As ProjectItem, ByVal dataFormClassName As String, ByVal templateClassName As String)
If pItem.Document IsNot Nothing Then
pItem.Document.Close(vsSaveChanges.vsSaveChangesPrompt)
End If
For i As Integer = 1 To pItem.FileCount
Dim dftFile As New IO.FileInfo(pItem.FileNames(CShort(i)))
Dim tr As IO.TextReader = dftFile.OpenText() 'IO.FileMode.Open, IO.FileAccess.ReadWrite, IO.FileShare.None)
Dim sb As New Text.StringBuilder
Dim newData As String = tr.ReadToEnd().Replace(dataFormClassName, templateClassName)
tr.Close()
Dim sw As New IO.StreamWriter(dftFile.FullName)
sw.Write(newData)
sw.Close()
Next
If pItem.FileCodeModel IsNot Nothing Then CType(pItem.FileCodeModel, FileCodeModel2).Synchronize()
For Each item As ProjectItem In pItem.ProjectItems
FixDataFormClassName(item, dataFormClassName, templateClassName)
Next
End Sub
I have a VB.NET project in Visual Studio 2008 that I created a specialized addin for. The addin prompts the user to select a database table, takes a template form class's files, copies them to another directory within the project, and renames the form class within the copied files. It then opens the new form and adds controls to it based on the fields in the database table.
The copying of the template form causes the background compiler to give 'duplicate member' errors, such as "Private Sub InitializeComponents(...) has multiple definitions with identical signatures," even though I renamed the files of the new form and the class name within them. Sometimes these errors go away before the new form is opened, but when they stick around the new form doesn't open correctly, and it throws an error instead.
I implemented some code to wait until there are zero errors in the error list before trying to open the new form. This has helped sometimes, but for some reason sometimes the errors don't go away at all until the addin is closed.
I was hoping someone could give tips on how to copy the template form and rename the copy without the background compiler ever noticing duplicate members. If that's not possible, then perhaps someone has an alternative?
Here is my code that copies and renames the template form:
Private Sub CreateDataForm(ByVal tableName As String, ByVal displayName As String) ', ByVal subDataForms As IList(Of Object))
Try
Dim dataFormClassName As String = "frm" & MakeValidName(displayName)
Dim dataFormFileName As String = dataFormClassName & cVBSuffix
Dim templateFileName As String = DataFormTemplate.Name
Dim templateClassName As String = Replace(templateFileName, cVBSuffix, String.Empty)
'copy form template to data forms folder
'copy files associated with main projectitem
Dim newPItem As ProjectItem = Nothing
For i As Integer = 1 To DataFormTemplate.FileCount
newPItem = DataFormsFolder.ProjectItems.AddFromFileCopy(DataFormTemplate.FileNames(CShort(i)))
Next
'copy files associated with sub projectitems
For Each item As ProjectItem In DataFormTemplate.ProjectItems
For i As Integer = 1 To item.FileCount
DataFormsFolder.ProjectItems.AddFromFileCopy(item.FileNames(CShort(i)))
Next
Next
newPItem.Name = dataFormFileName
newPItem.ContainingProject.Save()
'fix class name for dataform template
FixDataFormClassName(DataFormTemplate, dataFormClassName, templateClassName)
newPItem.ContainingProject.Save()
Application.DoEvents()
'get table metadata
Dim lGetColumnInfo As DataColumnCollection = GetColumnInfo(tableName)
'add field controls
ConvertColumnInfoToFormControls(newPItem, lGetColumnInfo, tableName, displayName)
Catch ex As Exception
DisplayExceptionMessage(ex)
End Try
End Sub
Private Shared Sub FixDataFormClassName(ByVal pItem As ProjectItem, ByVal dataFormClassName As String, ByVal templateClassName As String)
If pItem.Document IsNot Nothing Then
pItem.Document.Close(vsSaveChanges.vsSaveChangesPrompt)
End If
For i As Integer = 1 To pItem.FileCount
Dim dftFile As New IO.FileInfo(pItem.FileNames(CShort(i)))
Dim tr As IO.TextReader = dftFile.OpenText() 'IO.FileMode.Open, IO.FileAccess.ReadWrite, IO.FileShare.None)
Dim sb As New Text.StringBuilder
Dim newData As String = tr.ReadToEnd().Replace(dataFormClassName, templateClassName)
tr.Close()
Dim sw As New IO.StreamWriter(dftFile.FullName)
sw.Write(newData)
sw.Close()
Next
If pItem.FileCodeModel IsNot Nothing Then CType(pItem.FileCodeModel, FileCodeModel2).Synchronize()
For Each item As ProjectItem In pItem.ProjectItems
FixDataFormClassName(item, dataFormClassName, templateClassName)
Next
End Sub
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在我尝试通过 Visual Studio 的可扩展性 API 纠正此问题之后,我放弃了这种方法,现在在幕后完成所有肮脏的工作。我获取模板表单的文件,将它们复制到新目录,并在将新文件添加到项目之前通过 FileInfo 对象等在幕后更改它们的文件名和内容。这样,VS就永远不会处于出现“重复成员”错误的状态。
如果有人想查看代码,请大声喊叫,我会将其发布。
After all my attempts at correcting this via Visual Studio's Extensibility API, I gave up with that approach and now do all the dirty work behind the scenes. I take the template form's files, copy them to the new directory, and change their file names and contents all behind the scenes via FileInfo objects and whatnot before I add the new files to the project. This way, VS is never in a state where there are 'duplicate member' errors.
If anyone ever wants to see the code, holler and I'll post it up.