Aveva Marine VBNET 程式設計系列-搭建開發框架

南勝NanSheng發表於2023-09-28

引用的Dll

Aveva.ApplicationFramework.dll

Aveva.ApplicationFramework.Presentation

選單展示效果

Aveva Marine VBNET 程式設計系列-搭建開發框架

建立Attribute,用於反射來動態建立選單,不用每次都去寫command

Public Class MyAmFunctionAtt
    Inherits Attribute

    Private _menuName As String
    Public Property MenuName() As String
        Get
            Return _menuName
        End Get
        Set(ByVal value As String)
            _menuName = value
        End Set
    End Property
    Private _functionName As String
    Public Property FunctionName() As String
        Get
            Return _functionName
        End Get
        Set(ByVal value As String)
            _functionName = value
        End Set
    End Property

    Sub New(_menuNam As String, _functionName As String)
        Me.MenuName = _menuNam
        Me.FunctionName = _functionName
    End Sub
End Class

自定義類,在記憶體中儲存方法的資訊,方便後面反射呼叫。

Public Class MyAMFunction
    Private _att As MyAmFunctionAtt
    Public Property Att() As MyAmFunctionAtt
        Get
            Return _att
        End Get
        Set(ByVal value As MyAmFunctionAtt)
            _att = value
        End Set
    End Property

    Private _mi As MethodInfo
    Public Property Method() As MethodInfo
        Get
            Return _mi
        End Get
        Set(ByVal value As MethodInfo)
            _mi = value
        End Set
    End Property

    Sub New(mi As MethodInfo)
        Me.Att = mi.GetCustomAttributes(True).First(Function(att)
                                                        Return att.GetType().FullName = GetType(MyAmFunctionAtt).FullName
                                                    End Function)
        Me.Method = mi
    End Sub
End Class

外掛啟動載入的類

Public Class MianClsss
    Implements IAddin
    Public CurAss As Assembly = Assembly.GetExecutingAssembly()
    Public ReadOnly Property Description As String Implements IAddin.Description
        Get
            Return Me.GetType().FullName
        End Get
    End Property

    Public ReadOnly Property Name As String Implements IAddin.Name
        Get
            Return Me.GetType().FullName
        End Get
    End Property

    Public Sub Start(serviceManager As ServiceManager) Implements IAddin.Start
        Dim wm As WindowManager = serviceManager.GetService(GetType(WindowManager))
        'Dim cmd As New MyCommand(wm)
        'Dim cmdManager As CommandManager = serviceManager.GetService(GetType(CommandManager))
        'cmdManager.Commands.Add(cmd)
        Dim cbm As CommandBarManager = serviceManager.GetService(GetType(CommandBarManager))
        cbm.AllowCustomization = True
        cbm.BeginUpdate()
        Dim cbar = cbm.CommandBars.AddCommandBar(System.IO.Path.GetFileNameWithoutExtension(CurAss.Location))
        cbar.DockedPosition = DockedPosition.Top
        cbar.AllowHiding = False
        cbar.AllowFloating = True
        Dim assemblyDate = System.IO.File.GetLastWriteTime(System.Reflection.Assembly.GetExecutingAssembly().Location).ToString("yyyy年MM月dd日-HH點mm分")
        cbar.Caption = cbar.Key + $",軟體版本({assemblyDate})"
        '讀取全部的自定義命令
        Dim cmds = GetAllCommand()
        For Each item As KeyValuePair(Of String, List(Of MyAMFunction)) In cmds
            Dim curMenu As MenuTool = cbm.RootTools.AddMenuTool(item.Key, item.Key, Nothing)
            Dim it1 As MenuTool = cbar.Tools.AddTool(curMenu.Key)
            Dim curMenuItems = item.Value.OrderBy(Function(c)
                                                      Return c.Att.FunctionName
                                                  End Function).ToList()
            For Each myCmd As MyAMFunction In curMenuItems
                Dim cmdBtn As ButtonTool = cbm.RootTools.AddButtonTool(myCmd.Att.FunctionName, myCmd.Att.FunctionName, Nothing)
                cmdBtn.Tooltip = $"{myCmd.Att.MenuName}.{myCmd.Att.FunctionName}"
                AddHandler cmdBtn.ToolClick, Sub()
                                                 Try
                                                     wm.StatusBar.Text = $"正在執行命令{ myCmd.Att.FunctionName}..."
                                                     If myCmd.Method.DeclaringType Is Nothing Then Return
                                                     If myCmd.Method.IsStatic Then
                                                         myCmd.Method.Invoke(Nothing, {wm})
                                                     Else
                                                         myCmd.Method.Invoke(Activator.CreateInstance(myCmd.Method.DeclaringType), {wm})
                                                     End If
                                                     wm.StatusBar.Text = $"執行命令{ myCmd.Att.FunctionName}完成...."
                                                 Catch ex As Exception
                                                     MsgBox(ex.StackTrace)
                                                 End Try
                                             End Sub
                it1.Tools.AddTool(cmdBtn.Key)
            Next
        Next
        cbm.EndUpdate(True)
        cbm.SaveLayout()
    End Sub


    Public Sub [Stop]() Implements IAddin.Stop

    End Sub

    Public Function GetAllCommand() As Dictionary(Of String, List(Of MyAMFunction))

        Dim dicts As New Dictionary(Of String, List(Of MyAMFunction))

        Dim allClass As List(Of Type) = Me.CurAss.GetTypes().Where(Function(c)
                                                                       Return c.IsClass And c.IsPublic
                                                                   End Function).ToList()
        Dim mis As New List(Of MyAMFunction)

        For Each item As Type In allClass
            Dim curClsMis = item.GetMethods().Where(Function(m)
                                                        Return m.GetCustomAttributes(GetType(MyAmFunctionAtt), True).Any()
                                                    End Function).ToList()
            If curClsMis.Count > 0 Then
                For Each mi As MethodInfo In curClsMis
                    mis.Add(New MyAMFunction(mi))
                Next
            End If
        Next
        If mis.Count = 0 Then Return dicts
        For Each item As MyAMFunction In mis
            Dim temp As New List(Of MyAMFunction)
            If dicts.ContainsKey(item.Att.MenuName) Then temp = dicts(item.Att.MenuName)
            temp.Add(item)
            dicts(item.Att.MenuName) = temp
        Next
        Return dicts
    End Function
End Class

建立測試函式

Public Class MyAmCommand
    <MyAmFunctionAtt(NameOf(MyAmCommand), NameOf(測試功能))>
    Sub 測試功能(wm As WindowManager)
        MsgBox(NameOf(測試功能) + "ok")
    End Sub
End Class

修改檔案,讓外掛隨軟體啟動Aveva Marine VBNET 程式設計系列-搭建開發框架

在空白位置右鍵選擇剛才我們開發的外掛,即可達到開始的效果。

Aveva Marine VBNET 程式設計系列-搭建開發框架

相關文章