如何从Custom Control Designer写入源代码?

时间:2019-09-26 17:22:35

标签: vb.net visual-studio custom-controls designer

我正在尝试创建一个用户控件,该控件将修改模板生成的某些源代码。

我尝试从我创建的自定义ControlDesign中获取Assembly位置,但这是Visual Studio .exe位置,而不是源代码位置。

        Private Designer As BulkOpsVesselGridControlDesigner

        Public Sub New(ByVal Designer As BulkOpsVesselGridControlDesigner)
            MyBase.New(Designer.Component)
            Me.Designer = Designer
        End Sub

        Public Property GridType() As BulkOpsGrids
            Get
                Return Me.Designer.VesselGridControl.GridType
            End Get
            Set(ByVal value As BulkOpsGrids)
                Me.Designer.VesselGridControl.GridType = value

                If value = BulkOpsGrids.NewGrid Then
                    'Display Input from Developer
                    Dim gridName = InputBox("Please Type out the name of the Grid Type Without Spaces. Ex: WorkingCrane")
                    'TODO: Get file path programmatically (based on developer)
                    Dim path = "C:\BulkOpsWinUILib\UserControls\GridPropertyData\BulkOpsGridData.vb"

                    Dim fileExists As Boolean = IO.File.Exists(path)
                    Using sw As New IO.StreamWriter(IO.File.Open(path, IO.FileMode.OpenOrCreate))
                        'TODO: write logic for formatting and proper placedment
                        sw.WriteLine(gridName)
                    End Using
                End If
            End Set
        End Property

最终,如果开发人员选择“ newGrid”选项,我希望它自动提示输入有关网格定义的详细信息,然后将该选项添加到正确的源代码中。

希望是创建一个模板,该模板可用于帮助标准化我们如何在将来的应用程序中构建这些控件。模板本身将根据需要帮助创建和构建源代码。类似于设计器自动写入.designer文件的方法。

Image Of File Structure

1 个答案:

答案 0 :(得分:0)

听起来好像您想从控件的设计器代码中自动执行Visual Studio。您可以使用DTE Interface获得对IServiceProvider.GetService(Type) Method的引用。组件的Site Property实现了IServiceProvider接口。

一旦有了DTE参考,就可以检索有关当前加载的解决方案的信息,并执行VS Object模型允许的任何事情,包括将新项目添加到项目中。

下面的示例大致基于该问题,并显示了如何获取您所询问的各种路径信息。智能标记SomeProp属性设置器将设置自定义Label的text属性,以显示获取的信息。

' Project References:
'   • System.Design
'   • ENVDTE

Imports System.ComponentModel
Imports System.ComponentModel.Design
Imports System.Windows.Forms.Design

<Designer(GetType(TestControlDesigner))>
Public Class TestControl : Inherits Label
  Public Sub New()
    AutoSize = True
  End Sub
End Class

Public Class TestControlDesigner : Inherits ControlDesigner
  Private _actionLists As DesignerActionListCollection

  Public Overrides ReadOnly Property ActionLists As DesignerActionListCollection
    Get
      If _actionLists Is Nothing Then
        _actionLists = New DesignerActionListCollection({New MyActions(Me.Component)})
      End If
      Return _actionLists
    End Get
  End Property

  Private Class MyActions : Inherits DesignerActionList
    Public Sub New(component As System.ComponentModel.IComponent)
      MyBase.New(component)
    End Sub

    Private _SomeProp As String
    Public Property SomeProp As String
      Get
        Return _SomeProp
      End Get
      Set(value As String)
        _SomeProp = value
        Dim serviceProvider As IServiceProvider = Me.Component.Site
        Dim dte As EnvDTE.DTE = CType(serviceProvider.GetService(GetType(EnvDTE.DTE)), EnvDTE.DTE)
        Dim doc As EnvDTE.Document = dte.ActiveDocument
        Dim proj As EnvDTE.Project = doc.ProjectItem.ContainingProject
        Dim cntrl As Control = CType(Me.Component, Control)
        Dim sb As New System.Text.StringBuilder(1000)
        sb.Append($"Document Path: {doc.Path} {Environment.NewLine}")
        sb.Append($"Document Fullname: {doc.FullName} {Environment.NewLine}")
        sb.Append($"Project Filename: {proj.Properties.Item("FileName").Value} {Environment.NewLine}")
        sb.Append($"Project File Path: {proj.Properties.Item("LocalPath").Value} {Environment.NewLine}")
        cntrl.Text = sb.ToString()
      End Set
    End Property
  End Class
End Class