引用的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. 怎么利用大厂的API将大段音频转成文本

    日常办公中,我们经常要开会和写会议纪要.传统模式下,我们需要非常认真地听会议中每一句话,记下自己认为的核心的话,并在会后经过多次修改形成会议纪要.现在,聪明人已 经不那么干了,借助几百块的讯飞录音笔, ...

  2. 让AI支持游戏制作流程:从游戏设计到发布一个完整的生态系统

    目录 引言 随着游戏产业的快速发展,人工智能(AI)技术在游戏开发中的应用越来越广泛.游戏设计人员可以通过利用AI技术来自动化游戏中的某些流程,提高游戏制作的效率,降低开发成本,同时还可以创造出更加具 ...

  3. 基于DSP的设备振动信号的采集技术方案综述

    前记  在能源领域,由于很多地方都是无人值守,设备故障检测是一个必须面对的问题.笔者通过几个行业案例了解到,由于很多设备发生故障时候会产生特定频谱的声音,所以该行业对振动监测的需求特别强烈,由于涉及到 ...

  4. SQL 查询 总结 【行子查询 ; 列子查询 ; 表子查询 ; 自链接 ; 内连接 ;外连接 ; 无规则链接 ……】

    简单介绍一下连接方式: 1.1.使用无连接规则连接两表  无限规则  也就简单的 select * from tableA , tableB  即得到一个笛卡尔积.  什么是 笛卡尔积 在 我的 另外 ...

  5. K8S | 容器和Pod组件

    对比软件安装和运行: 一.场景 作为研发人员,通常自己电脑的系统环境都是非常复杂,在个人的习惯上,是按照下图的模块管理电脑的系统环境: 对于「基础设施」.「主机操作系统」.「系统软件」来说,通常只做配 ...

  6. Android实时获取摄像头画面传输至PC端

    前言 最近在做一个PC端小应用,需要获取摄像头画面,但是电脑摄像头像素太低,而且位置调整不方便,又不想为此单独买个摄像头.于是想起了之前淘汰掉的手机,成像质量还是杠杠的,能不能把手机摄像头连接到电脑上 ...

  7. 最为常用的Laravel操作(3)-模板

    Blade 模板引擎 模板继承 定义布局: <!-- 存放在 resources/views/layouts/app.blade.php --> <html> <head ...

  8. ASP.NET Core - 日志记录系统(一)

    一.日志记录 日志记录是什么?简单而言,就是通过一些方式记录应用程序运行中的某一时刻的状态,保留应用程序当时的信息.这对于我们进行应用程序的分析.审计以及维护有很大的作用. 作为程序员,我们恐怕谁也不 ...

  9. docker部署zabbix 6.0高可用集群实验

    0 实验环境 虚拟机,postgresql本地部署,zabbix server及nginx容器部署 1 postgresql 参看前作 <postgresql + timescaledb离线安装 ...

  10. OceanBase 分布式存储管理

    分布式存储管理 分区表管理 定义 把普通的表的数据按照一定的规则划分到不同的区块内,同一区块的数据物理上存储在一起. 每个分区还能按照一定的规则再拆分成多个分区,这种分区表叫做二级分区表. 分区分类 ...