引用的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

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

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

Aveva Marine VBNET 编程系列-搭建开发框架的更多相关文章

  1. 猫哥网络编程系列:HTTP PEM 万能调试法

    注:本文内容较长且细节较多,建议先收藏再阅读,原文将在 Github 上维护与更新. 在 HTTP 接口开发与调试过程中,我们经常遇到以下类似的问题: 为什么本地环境接口可以调用成功,但放到手机上就跑 ...

  2. 完毕port(CompletionPort)具体解释 - 手把手教你玩转网络编程系列之三

       手把手叫你玩转网络编程系列之三    完毕port(Completion Port)具体解释                                                    ...

  3. 27、通过visual s'tudio 验证 SOCKET编程:搭建一个TCP服务器

    本文就是在windows下进行socket编程,搭建一个TCP客户端. 在visual studio下编程,首先在windows下进行初始化(这点在linux下是不需要的): /* 初始化 Winso ...

  4. AngularJS体验式编程系列文章

    AngularJS体验式编程系列文章,将介绍如何用angularjs构建一个强大的web前端系统.angularjs是由Google团队开发的一款非常优秀web前端框架.在当前如此多的web框架下,a ...

  5. shell编程系列25--shell操作数据库实战之备份MySQL数据,并通过FTP将其传输到远端主机

    shell编程系列25--shell操作数据库实战之备份MySQL数据,并通过FTP将其传输到远端主机 备份mysql中的库或者表 mysqldump 常用参数详解: -u 用户名 -p 密码 -h ...

  6. 学习ASP.NET Core Blazor编程系列二——第一个Blazor应用程序(上)

    学习ASP.NET Core Blazor编程系列一--综述 一.概述 Blazor 是一个生成交互式客户端 Web UI 的框架: 使用 C# 代替 JavaScript 来创建信息丰富的交互式 U ...

  7. [ 高并发]Java高并发编程系列第二篇--线程同步

    高并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求, ...

  8. 猫哥网络编程系列:详解 BAT 面试题

    从产品上线前的接口开发和调试,到上线后的 bug 定位.性能优化,网络编程知识贯穿着一个互联网产品的整个生命周期.不论你是前后端的开发岗位,还是 SQA.运维等其他技术岗位,掌握网络编程知识均是岗位的 ...

  9. 【linux草鞋应用编程系列】_6_ 重定向和VT100编程

    一.文件重定向     我们知道在linux shell 编程的时候,可以使用文件重定向功能,如下所示: [root@localhost pipe]# echo "hello world&q ...

  10. 【linux草鞋应用编程系列】_5_ Linux网络编程

    一.网络通信简介   第一部分内容,暂时没法描述,内容实在太多,待后续专门的系列文章.   二.linux网络通信     在linux中继承了Unix下“一切皆文件”的思想, 在linux中要实现网 ...

随机推荐

  1. 4. JDK相关设置

    恐惧是本能,行动是信仰(在此感谢尚硅谷宋红康老师的教程) 1. 项目的 JDK 设置 File-->Project Structure...-->Platform Settings --& ...

  2. Java输出100以内的所有质数

    代码如下: public static void main(String[] args) { for(int k=2;k<=100;k++) { boolean flag = true; for ...

  3. C++面试八股文:用过std::set/std::map吗?

    某日二师兄参加XXX科技公司的C++工程师开发岗位第27面: 面试官:用过std::set/std::map吗? 二师兄:用过. 面试官:能介绍一下二者吗? 二师兄:std::set是一个有序的集合, ...

  4. 【小小Demo】在线聊天小🌰子

    easy-chat 一个简单的即时通讯demo. 环境 jdk1.8 idea maven springboot 2.1.1.RELEASE websocket 项目启动 修改maven设置 打开ID ...

  5. Java_Day17_作业

    1:需求:递归删除带内容的目录 假设删除当前项目下的目录:demo,demo中可以有文件夹自己给出 2:需求:请大家把E:\JavaSE目录下所有的java结尾的文件的绝对路径给输出在控制台. 3:下 ...

  6. python开发之远程开发工具对比

    前言 除了本地开发外,还有一种常见的开发方式就是远程开发,一般情况是一台Windows或mac笔记本作为日常使用的电脑,另有一台linux服务器作为开发服务器.开发服务器的性能往往较强,这样远程开发的 ...

  7. 【转载】Linux虚拟化KVM-Qemu分析(十一)之virtqueue

    转载自: 作者:LoyenWang 出处:https://www.cnblogs.com/LoyenWang/ 公众号:LoyenWang 版权:本文版权归作者和博客园共有 转载:欢迎转载,但未经作者 ...

  8. Composer 镜像原理 (1) —— 初识 Composer

    相关文章 Composer 镜像原理 (1) -- 初识 Composer Composer 镜像原理 (2) -- composer.json Composer 镜像原理 (3) -- 完结篇 何为 ...

  9. win10安装mysql时提示错误:mysqld: Can't change dir to 'C: oftware\mysql\data\' (Errcode: 2 - No such file or directory)

    win10安装解压版mysql时,提示错误: 2019-10-22 09:02:00 2004 [ERROR] Can't find messagefile 'C:\WINDOWS\system32\ ...

  10. centOS7 磁盘扩容(2T以上)

    centOS7 磁盘扩容 1.安装parted分区工具 yum install -y parted 2.查看服务器分区情况 #fdisk -l 或者 lsblk 找到新增磁盘名称 例如/dev/sdb ...