Aveva Marine VBNET 编程系列-搭建开发框架

发布时间 2023-09-28 14:37:32作者: 南胜NanSheng

引用的Dll

Aveva.ApplicationFramework.dll

Aveva.ApplicationFramework.Presentation

菜单展示效果

创建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

修改文件,让插件随软件启动

在空白位置右键选择刚才我们开发的插件,即可达到开始的效果。