AVEVA .Net 菜单自定义

AVEVA .Net 菜单自定义

AVEVA .Net Command and Menu Customisation

eryar@163.com

 

摘要Abstract:以一个具体实例详细介绍AVEVA .Net中自定义菜单的原理及方法。掌握了自定义菜单的方法就可以对二次开发的程序进行分类和整理,便于用户使用。

关键字Key words:AVEVA .Net、Addin Commands、Menu Customisation、PDMS、二次开发

 

一、概述 Introduction

通过《AVEVA .Net Quick Start Guide》这篇文章,大家对AVEVA .Net的二次开发有了个大概认识,但是这样并不能编写出实际有用的二次开发插件(Addin)。本文再深入一步,介绍自定义菜单方法,在菜单中调用二次开发的插件,便于用户操作。

用户通过菜单、右键菜单命令、工具条来调用开发的插件。通用程序框架CAF(The Common Application Framework)通过类CommandBarManager来提供了创建菜单、工具条等的接口。也提供了与这些工具交互事件的接口,这种方法CAF虽然支持但不推荐。

通用程序框架CAF还支持通过UIC(用户界面自定义文件User Interface Customisation)文件来自定义菜单、工具条等,UIC文件是XML格式的。

基于XML定义的菜单及工具条需要有个机制将用户界面实体与需要调用的相关功能关联上。为了实现这人目的,插件(Addins)功能通过一些命令对象(command objects)暴露出来。插件通过类CommandManager来加载这些命令对象。XML定义中可以包含用户界面实体如菜单入口、工具条的按钮及与其相关的命令对象。选择相应的菜单或点击工具条上的按钮都可以导致相关联的命令被执行。

基于命令模型的一个好处就是将用户界面或显示层与逻辑层解耦。程序逻辑层就与显示层没有什么直接关系了。若程序的状态需要对用户界面上的操作做出反映,程序只需要修改命令的状态即可。命令对象知道它与哪个用户界面实体关联,所以确保其内部状态反映相应的用户界面。这对一些状态是很简单的,如“enabled”、“visible、“checked”;但对动态程序状态就有点复杂了,如“combo-box”。

 

二、编写命令类 Writing a Command Class

如下所示的代码是一个简单的命令类示例,用来管理一个可停靠窗口的可见性,代码中是控制AttributeBrowser 可停靠窗口。通用程序框架CAF提供了一个抽象的命令类Command,所有的命令类都必须派生自Command类。在其构造函数中应该设置属性Key,在UIC文件中是通过Key这个属性来找到相应的命令,后面将会以一个实例来说明。

 

  1using System; 
  2
  3using System.Collections.Generic; 
  4
  5using System.Text; 
  6
  7using Aveva.ApplicationFramework.Presentation; 
  8
  9namespace Aveva.Presentation.AttributeBrowserAddin 
 10
 11
 12
 13/**//// <summary> 
 14
 15/// Class to manage the visibility state of the AttributeBrowser docked window 
 16
 17/// This command should be associated with a StateButtonTool. 
 18
 19/// </summary> 
 20
 21public class ShowAttributeBrowserCommand : Command 
 22
 23
 24
 25private DockedWindow _window; 
 26
 27/**//// <summary> 
 28
 29/// Constructor for ShowAttributeBrowserCommand 
 30
 31/// </summary> 
 32
 33/// <param name="window">The docked window whose visibilty state will be managed.</param> 
 34
 35public ShowAttributeBrowserCommand(DockedWindow window) 
 36
 37
 38
 39// Set the command key 
 40
 41this.Key = "Aveva.ShowAttributeBrowserCommand"; 
 42
 43// Save the docked window 
 44
 45            _window = window; 
 46
 47// Create an event handler for the window closed event 
 48
 49            _window.Closed += new EventHandler(_window_Closed); 
 50
 51// Create an event handler for the WindowLayoutLoaded event 
 52
 53            WindowManager.Instance.WindowLayoutLoaded += new EventHandler(Instance_WindowLayoutLoaded); 
 54
 55
 56
 57void Instance_WindowLayoutLoaded(object sender, EventArgs e) 
 58
 59
 60
 61// Update the command state to match initial window visibility 
 62
 63this.Checked = _window.Visible; 
 64
 65
 66
 67void _window_Closed(object sender, EventArgs e) 
 68
 69
 70
 71// Update the command state when the window is closed 
 72
 73this.Checked = false; 
 74
 75
 76
 77        /**//// <summary> 
 78
 79        /// Override the base class Execute method to show and hide the window 
 80
 81        /// </summary> 
 82
 83        public override void Execute() 
 84
 85        
 86
 87            if (this.Checked) 
 88
 89            
 90
 91                _window.Show(); 
 92
 93            } 
 94
 95            else 
 96
 97            
 98
 99                _window.Hide(); 
100
101            } 
102
103        } 
104
105    } 
106
107
108
109

抽象基类Command提供了以下方法,其派生类中可以重载:

l void Execute():必须被重载,在执行命令时调用这个函数;

l CommandState GetState():这个函数由通用程序框架CAF调用,以便更新用户界面或上下文菜单。返回值是一个CommandState枚举值,反应了命令的状态。枚举值用来位来表示命令状态,这些状态可以使用位的或OR操作。

l String Description:命令的描述;

l void Refrest(string context):当CommandManager.ApplicationContext的属性更改时都会调用这个方法。这也就给了一个更新其Enabled或visible状态的机会。

抽象基类Command也有一些属性可以用来更新用户界面上的状态:

l bool Checked:若命令与像StateButtonTool这样的用户界面关联,则此属性值与用户界面上的状态会同步;

l bool Enabled:此属性值的改变将会影响所有与其关联的用户界面;

l ArrayList List:此属性允许命令可以与有字符列表的用户界面交流。如ComboBoxTool;

l int SelectedIndex:此属性表示被用记选中的列表中的索引值;

l object Value:此属性保存了当前关联的用户界面实体;

l bool ValueChanged:通用程序框架CAF在调用命令类的Execute方法之前,若用户界面的值改变时会设置此属性的值。当命令执行结束后此值会被清除;

l bool Visible:此属性值的改变将会影响所有与其关联的用户界面;

在通用程序框架CAF中注册一个命令是通过向CommanManagers.Commands的集合中添加一个命令实例来实现的。程序代码如下所示:

 

 1 // Create and register addins commands 
 2 
 3 // Get the CommandManager 
 4 
 5 CommandManager commandManager = (CommandManager)serviceManager.GetService(typeof(CommandManager)); 
 6 
 7 ShowAttributeBrowserCommand showCommand = new ShowAttributeBrowserCommand(attributeListWindow); 
 8 
 9 commandManager.Commands.Add(showCommand); 
10 

 

 

三、命令事件 Command Events

命令基类Command提供了两个事件BeforeCommandExecute和CommandExecuted给程序员,用来响应命令的执行,即在命令执行前后做些处理。示例代码如下:

 

 1 Command anotherCommand = commandManager.Commands["KeyOfCommand"]; 
 2 
 3 anotherCommand.BeforeCommandExecute += new System.ComponentModel.CancelEventHandler(anotherCommand_BeforeCommandExecute); 
 4 
 5 anotherCommand.CommandExecuted += new EventHandler(anotherCommand_CommandExecuted); 
 6 
 7 //The BeforeCommandExecute event handler is of type  
 8 
 9 //CancelEventHandler and is passed a CancelEventArgs object  
10 
11 //which enables the command execution to be cancelled by setting  
12 
13 //the Cancel property to true. 
14 
15 void anotherCommand_BeforeCommandExecute(object sender, System.ComponentModel.CancelEventArgs e) 
16 
17 { 
18 
19     e.Cancel = true; 
20 
21 } 
22 
23 

 

四、菜单自定义 Menu Customisation

用户使用插件的方式通常都是通过使用菜单或命令栏上的按钮。如前文所述,通用程序框架CAF提供了自定义菜单和命令栏的机制,即通过配置“User Interface Customisation”(UIC)文件。下面将会对UIC文件的细节进行描述,如怎样配置通用程序框架CAF来加载UIC文件,通过用户交互的自定义工具来编辑UIC文件等等。

 

五、配置要加载UIC文件的模块 Configuring a Module to Load a UIC File

每个基于通用程序框架CAF的插件都有一个XML格式的配置文件,包含了程序启动时需要加载的一系列UIC文件。此文件的默认路径就是安装目录,文件名的命令方式为<模块名>Customisation.xml。例如AVEVA Marine模块Hull Design就有一个名为HullDesignCustomisation.xml的配置文件,文件内容如下所示。默认情况下UIC文件也希望在相同的目录下。标专“$1”表示UIC文件的路径将会由当前工程名代替。

 

<?xml version="1.0" encoding="utf-8"?> 

<UICustomizationSet xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 

<UICustomizationFiles> 

<CustomizationFile Name="Hull General" Path="AVEVA.Marine.UI.HullGeneral.uic" /> 

<CustomizationFile Name="Hull Design" Path="AVEVA.Marine.UI.HullDesign.uic" /> 

<CustomizationFile Name="Project" Path="$1.uic" /> 

<CustomizationFile Name="StatusControllerAddin" Path="StatusController.uic" /> 

</UICustomizationFiles> 

</UICustomizationSet> 

 

配置文件中UIC文件的顺序是很重要的,它表示了程序加载这些自定义界面的顺序。一个新的UIC文件可以加载到一个模块中,通过在其配置文件中简单添加一行即可。

与在模块的配置文件中添加UIC文件的功能类似的方法是在程序中编码实现对UIC文件的添加,通过CommandBarManager的方法AddUICustomisationFile来编码实现UIC文件的添加。程序代码如下所示:

 

1 // Load a UIC file for the AttributeBrowser. 

3 CommandBarManager commandBarManager = (CommandBarManager)serviceManager.GetService(typeof(CommandBarManager)); 

5 commandBarManager.AddUICustomizationFile("AttributeBrowser.uic", "AttributeBrowser"); 

 

通过具体实例将会看出,通过自定义对话框,配置文件中的UIC文件将会被管理,不用自己手动更改UIC文件中的内容。

 

六、UIC文件的编辑 Editing UIC File

UIC文件是通过通用程序框架CAF的内置交互工具来创建与编辑的,不需要亲自更其中内容。通过在工具栏上右键,选择Customize来启动自定义对话框,如下图所示:

自定义对话框主要由七个部分组成:

① CommandBar Preview Area

② Active Customisation File

③ Tree showing CommandBars

④ List of tools

⑤ Property grid

⑥ Action buttons

⑦ Resource Editor

以下将会以具体实例来介绍相应的用法。更多细节请参考《AVEVA .NET Customisation User Guide》。通过自定义对话框,UIC文件中的内容将会被AVEVA管理,所以创建自定义的菜单或工具栏按钮,都从这个自定义对话框中编辑,还是很方便。

 

七、程序实例 Codes

本节以一个具体实例来说明AVEVA .Net的菜单的自定义及与相关命令的关联方法。步骤如下:

1. 创建一个C#的类库(Class Library),工程名为HelloWorld,并选择.NET Framework 3.5,如下图所示:

2. 添加引用Aveva.ApplicationFramework.dll和 Aveva.ApplicationFramework.Presentation.dll,如下图所示:

添加完后的引用库如下图所示:

3. 编写一个插件类HelloAddin,派生自IAddin,并实现那四个虚函数,程序代码如下所示:

 

 1 using System; 
 2 
 3 using System.Collections.Generic; 
 4 
 5 using System.Text; 
 6 
 7 using Aveva.ApplicationFramework; 
 8 
 9 using Aveva.ApplicationFramework.Presentation; 
10 
11 namespace HelloWorld 
12 
13 { 
14 
15 public class HelloAddin : IAddin 
16 
17 { 
18 
19 #region IAddin Members 
20 
21 public string Description 
22 
23 { 
24 
25             get 
26 
27 { 
28 
29 return "AVEVA .Net Menu Customisation Demo."; 
30 
31 } 
32 
33 } 
34 
35 public string Name 
36 
37 { 
38 
39             get 
40 
41 { 
42 
43 return "HelloAddin"; 
44 
45 } 
46 
47 } 
48 
49 public void Start(ServiceManager serviceManager) 
50 
51 { 
52 
53 // Stop for attaching to the process. 
54 
55             System.Windows.Forms.MessageBox.Show("Debug"); 
56 
57 } 
58 
59 public void Stop() 
60 
61 { 
62 
63 } 
64 
65 #endregion 
66 
67 } 
68 
69 } 
70 
71 

4. 添加一个用户控件(User Control)而不是一个窗口(Windows Form),如下图所示:

5. 自定义用户控件上内容,本例仅在其上添加最简单的label为例,添加后并将其内容改为“Hello World”,如下图所示:

6. 添加命令类HelloWorldCommand,派生自抽象基类Command,并实现几个关键的方法。如在其构造函数中添加Key属性,Key属性在后面添加菜单时很重要。还有必须实现的Execute方法。程序代码如下所示:

 

 1 using System; 
 2 
 3 using System.Collections.Generic; 
 4 
 5 using System.Text; 
 6 
 7 using Aveva.ApplicationFramework.Presentation; 
 8 
 9 namespace HelloWorld 
10 
11 { 
12 
13 class HelloWorldCommand : Command 
14 
15 { 
16 
17 private DockedWindow myWindow; 
18 
19 // Default Constructor. 
20 
21 public HelloWorldCommand(DockedWindow window) 
22 
23 { 
24 
25 // Set the command key. 
26 
27 // This is very import!!! 
28 
29 this.Key = "Aveva.HelloWorldCommand"; 
30 
31 // Save the docked window. 
32 
33             myWindow = window; 
34 
35 // Create an event handler for the window closed event. 
36 
37             myWindow.Closed += new EventHandler(_window_Closed); 
38 
39 // Create an event handler for the windowLayoutLoaded event. 
40 
41             WindowManager.Instance.WindowLayoutLoaded += new EventHandler(Instance_WindowLayoutLoaded); 
42 
43 } 
44 
45 void _window_Closed(object sender, EventArgs e) 
46 
47 { 
48 
49 this.Checked = false; 
50 
51 } 
52 
53 void Instance_WindowLayoutLoaded(object sender, EventArgs e) 
54 
55 { 
56 
57 // Update the command state to match initial window visibility. 
58 
59 this.Checked = myWindow.Visible; 
60 
61 } 
62 
63 // This method must be overriden to provide the command execution functionality. 
64 
65 public override void Execute() 
66 
67 { 
68 
69 // Always show the DockedWindow. 
70 
71             myWindow.Show(); 
72 
73 } 
74 
75 } 
76 
77 } 
78 
79 

7. 在派生自IAddin的类中的Start方法中添加创建可停靠窗口的代码,并将命令添加通用程序框架的命令集合中去,程序如下所示:

 

 1 public void Start(ServiceManager serviceManager) 
 2 
 3 { 
 4 
 5 // Stop for attaching to the process. 
 6 
 7             System.Windows.Forms.MessageBox.Show("Debug"); 
 8 
 9 // Get the WindowManager service. 
10 
11             WindowManager windowManger = (WindowManager)serviceManager.GetService(typeof(WindowManager)); 
12 
13 // Create a docked window to host and Hello World User control. 
14 
15             DockedWindow myWindow = windowManger.CreateDockedWindow("Aveva.HelloAddin.UserControl", 
16 
17 "HelloWorld", 
18 
19 new HelloAddinControl(), 
20 
21                 DockedPosition.Right); 
22 
23 // Create and register Addin's command. 
24 
25             CommandManager commandManager = (CommandManager)serviceManager.GetService(typeof(CommandManager)); 
26 
27             HelloWorldCommand showCommand = new HelloWorldCommand(myWindow); 
28 
29             commandManager.Commands.Add(showCommand); 
30 
31 } 
32 
33 

8. 编译工程(Build HelloWorld),并将生成的动态库(HelloWorld.dll)复制到AVEVA的安装目录;

9. 修改配置文件,使其加载该插件,修改方法如下图所示:

10. 添加自定义菜单,方便插件的调用。在工具栏的任意位置点击鼠标右键,选择Customize,出现自定义的对话框,并在Active Customization File 的选项框中选择Module,如下图所示:

在Menubar中添加自定义菜单项,将其名称改为MenuTest,如下图所示:

在对话框中间任意位置点鼠标右键,添加一个按钮(button),如下图所示:

修改按钮的标题为ButtonTest,修改其命令(Command),在Core Command中选择我们创建的命令类的Key,如下图所示:

将按钮拖到左边的菜单下后,Apply结束。如下图所示:

11. 自定义后的菜单如下图所示:

 

八、结论 Conclusion

通过实例对AVEVA .Net的二次开发有了便全面的认识,可以通过自定义菜单方便调用二次开发的插件。自定义菜单或者工具栏按钮主要是通过自定义对话框来实现,不需要程序员手动修改UIC文件,交互操作使用方便。

若有术语用词不当之处,敬请指出。eryar@163.com

 

九、参考资料 Bibliography

1. AVEVA .Net Customisation User Guide 本文基本上是对这个Guide的部分翻译。

2. GoF book: Design Patterns Elements of Reusable Object-Oriented Software 对Command模式感兴趣的可以一读。

 

PDF Version: AVEVA .Net Command and Menu Customisation

时间: 2024-08-19 02:02:45

AVEVA .Net 菜单自定义的相关文章

Flex/AS3/flash player支持屏蔽右键菜单,自定义菜单,并设置相应的菜单事件(示例,图解)

Flex/AS3/flash player支持屏蔽右键菜单,自定义菜单,并设置相应的菜单事件(示例,图解) 播放器 版本 11.2以后支持右键菜单屏蔽及自定义菜单 1.更新播放器 ,11.2 以上版本 http://download.macromedia.com/get/flashplayer/updaters/11/playerglobal11_3.swc http://download.macromedia.com/get/flashplayer/updaters/11/playerglob

WORDPRESS菜单自定义链接设置打开新窗口教程

WordPress自定义菜单可以添加自定义链接,也就是设置一个自定义的url作为菜单,但是默认个自定义链接打开方式是当前页面跳转,如何给这个链接设置target='_blank'属性呢? 在WordPress源码中找到可以改变菜单属性的一个filter,位于D:\xampp\htdocs\wp\wp-includes\nav-menu-template.php: /**  * Filter the sorted list of menu item objects before generatin

怎样使用Win7系统开始菜单自定义最近打开的程序

  当我们在电脑中运行某些软件或文档等程序时,在开始菜单中也会显示着最近打开过的程序记录,这样可以让我们更加快捷使用,在ghost win7中默认是显示10条最近打开程序,但记录太多程序让开始菜单显示很是混乱不美观,其实我们是可以自定义开始菜单最近打开的程序数目的,下面来看看设置技巧吧. 1.打开电脑之后,在桌面左下方"开始"菜单里面右键点击或"任务栏"点击右键,并然后选择"属性"选项; 2.直接打开任务栏和开始菜单属性,将其切换到"开

javascript鼠标右键菜单自定义效果_javascript技巧

本文实例讲解了javascript鼠标右键菜单的实现方法,分享给大家供大家参考,具体内容如下 效果图: 具体代码: <html> <head> <meta charset="gb2312" /> <title></title> <style> #menu{ border:solid 1px gray; width:100px; display:none; position:absolute; background-

实现Sbo系统与用户菜单自定义

一个朋友请问我,怎样实现Sbo的系统模块主菜单的自定义标题设置.事实上,这个实现是简单的,既然有需要,花了一点时间,将此功能集成到了我们的富盛Sbo插件集中. 在富盛Sbo插件集中的系统设置中我们新增一个项功能--http://www.aliyun.com/zixun/aggregation/12553.html">自定义菜单,打开菜单出现以下自定义菜单的配置窗口,缺省的情况下,考虑到Sbo客户端的模块菜单项下的可编程功能,对于Sbo模块菜单下的所有系统菜单和第三方Addon用户菜单都可以

Win8系统开始菜单自定义的方法

1. 调整位置:鼠标左击应用不放,可以移动到相应位置. 2. 组名修改:鼠标单机右下角滑动条旁的图标,显示缩小的开始菜单,在每个区域上右击,可以修改名称,拖动可以调整应用组的位置.在所有程序界面右击程序可以进行固定开始菜单.卸载.查看位置等操作.         注:更多请关注电脑教程栏目,三联电脑办公群:189034526欢迎你的加入

Notepad++ 右键菜单自定义配置

  问:想在右键菜单里面多加几个功能,怎么加,比如区块注释 答:其实notepad++的配置文件存放路径不在自己的软件路径,而存在于 xp:C:\Documents and Settings\Administrator\Application Data\Notepad++\contextMenu.xml win7/8 :c:\users\xxx\AppDate\Roaming\Notepad++\contextMenu.xml   只需要修改此xml文件,并重启notepad++即可看到效果.

Windows8系统电脑开始菜单自定义的方法

适用范围: win8 操作步骤: 1. 调整位置:鼠标左击应用不放,可以移动到相应位置. 2. 组名修改:鼠标单机右下角滑动条旁的图标,显示缩小的开始菜单,在每个区域上右击,可以修改名称,拖动可以调整应用组的位置.在所有程序界面右击程序可以进行固定开始菜单.卸载.查看位置等操作.  

详解Win7“自定义开始菜单”设置技巧

Win7系统的开始菜单中会显示我们最近使用过的程序或项目的快捷方式,如果想对Win7的开始菜单做一些个性设置,应该怎么办呢? 最近学到一个小技巧,可以轻松自定义Win7系统的开始菜单,在这里和大家一起分享. Win7开始菜单显示最近使用过的程序或项目,可以从右键菜单中选择"从列表中删除" 操作步骤很简单,先用鼠标右键点击Win7的圆形"开始"按钮,然后选择"属性",打开"自定义开始菜单"的设置面板. 在"开始菜单&q