上一章我们利用DgnPrimitiveTool和DgnElementSetTool捕获到了鼠标的数据键和拒绝键(当然也能捕获到用户的键盘输入),这些都是在Mstn中发生的事件。其实,Mstn中还有更多的事件在发生而且我们可以来捕获它们。下表列出最常见的事件类型以及事件处理函数。
事件类型 |
事件处理函数 |
参考设计文件 |
ReferenceAttachedEvent的方法 |
卸载参考文件 |
ReferenceDetachedEvent的方法 |
打开或关闭设计文件 |
NewDesignFileEvent(附加到NewDesignFileEvent中) |
“另存为”命令 |
FileSaveAsEvent的方法 |
激活模型 |
ModelChangedEvent的方法 |
跟踪元素的变化 |
ElementChangedEvent的方法 |
选择集的变化 |
SelectionChangedEvent的方法 |
层的变化 |
LevelChangeEvent的方法 |
选择不同视图 |
SelectedViewChangedEvent的方法 |
卸载程序 |
UnloadAnyAppEvent的方法 |
本章我们以一个例子来进一步使用ILevelChangeEvents和NewDesignFileEventHandler。该例子在一个对话框中显示当前DGN文件中的层,如果您在Mstn的层管理器中新增、删除或改名层后,这个对话框中的层信息会同步修改。另外,当您打开一个新文件时,该对话框中的层信息也会自动更新。下面我们就一步步来构造这个功能。
1.在您的VS中新建一个WinForm,取名叫做LevelChangedForm并给其添加唯一的一个列表框控件。生成的窗体如下图所示:
2.对该窗体进行如下属性设置。注意,我们对列表框的Modifiers属性设置为Public,这样就不必像上一章介绍的那样到LevelChangedForm.Designer.cs文件中直接修改代码了。将列表框的Sorted属性设置为True能使其按字母顺序显示内容。
Form (Name) = LevelChangedForm / FormBorderStyle = FixedDialog / MaximizeBox = False / MinimumBox = False
/ ShowIcon = False / Size = 288,423 / Text = LevelChangedForm
ListBox (Name) = listBox1 / Location = 5,13 / Modifiers = Public / Size = 272,372 / Sorted = True
3.以代码方式打开LevelChangedForm.cs并修改其内容。最终完整的代码如下。这里需要注意几点:①将LevelChangedForm的基类由Form改成Adapter;②在打开本窗体时会调用到LevelChangedForm_Load方法,在该方法中通过listBox1.Items.Add来将当前DGN文件中的层添加到列表框中;③在窗体的构造函数中,我们添加了两个事件处理器,在窗体被关闭时系统会调用到LevelChangedForm_FormClosed方法,我们在该方法中移除了两个事件处理器。LevelChangedEvent事件会在层发生变化时被激发,NewDesignFileEvent事件会在当前文件发生变化时被激发,在这两个事件处理器中我们都调用了PopulateLevelList对ListBox内容进行更新。
using Bentley.DgnPlatformNET; using Bentley.MstnPlatformNET; using Bentley.MstnPlatformNET.WinForms; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using static Bentley.MstnPlatformNET.AddIn; namespace csAddins { public partial class LevelChangedForm : //Form Adapter { public LevelChangedForm() { InitializeComponent(); //添加层变化以及打开新文件会触发的事件处理函数 MyAddin.Addin.LevelChangeEvent += LevelChangeEventHandler; MyAddin.Addin.NewDesignFileEvent += NewDesignFileEventHandler; } //界面加载时,获取当前文件中所有的层名并显示到listbox中 private void LevelChangedForm_Load(object sender, EventArgs e) { FileLevelCache fileLevelCache=Session.Instance.GetActiveDgnFile().GetLevelCache(); LevelHandleCollection levelHandleCol = fileLevelCache.GetHandles(); foreach(LevelHandle levelHandle in levelHandleCol) { listBox1.Items.Add(levelHandle.Name); } } //界面关闭时要卸载掉我们之前添加的事件处理函数 private void LevelChangedForm_FormClosed(object sender, FormClosedEventArgs e) { MyAddin.Addin.LevelChangeEvent -= LevelChangeEventHandler; MyAddin.Addin.NewDesignFileEvent -= NewDesignFileEventHandler; } //根据参数eventArgsIn.Change判断层发生了何种变化,进而决定是否更新界面中的层名 private void LevelChangeEventHandler(AddIn senderIn, LevelChangeEventArgs eventArgsIn) { if (eventArgsIn.Change == LevelChangeEventArgs.ChangeType.Create || eventArgsIn.Change == LevelChangeEventArgs.ChangeType.Delete || eventArgsIn.Change == LevelChangeEventArgs.ChangeType.TableRewrite || eventArgsIn.Change == LevelChangeEventArgs.ChangeType.ChangeName) PopulateLevelList(); } //打开新文件时更新界面上的层名 private void NewDesignFileEventHandler(AddIn sender, NewDesignFileEventArgs eventArgs) { if (AddIn.NewDesignFileEventArgs.When.AfterDesignFileOpen == eventArgs.WhenCode) PopulateLevelList(); } private void PopulateLevelList() { listBox1.Items.Clear(); LevelHandleCollection levelCollection = Session.Instance.GetActiveDgnFile().GetLevelCache().GetHandles(); foreach (LevelHandle myLvl in levelCollection) listBox1.Items.Add(myLvl.Name); } } }
4.打开commands.xml文件,新增命令csAddins DemoForm LevelChanged并指定其处理函数为csAddins.DemoForm.LevelChanged。如果您对XML格式的命令表文件还不熟悉,请参考第四章的相关主题。
5.打开DemoForm.cs,翻到代码尾部增加命令处理函数LevelChanged如下。这段代码以单实例(Singleton)模式打开LevelChangedForm,即保证同时只能有一个该窗体被打开。
private static LevelChangedForm myLevelForm = null; public static void LevelChanged(string unparsed) { if (null == myLevelForm || myLevelForm.IsDisposed) { myLevelForm = new LevelChangedForm(); myLevelForm.AttachAsTopLevelForm(MyAddin.Addin, false); myLevelForm.Show(); } else myLevelForm.Activate(); }
6.完成了代码的编写后就让我们来实际测试一下。首先在VS中重新生成csAddins。然后启动Mstn,键入mdl load csAddins装载csAddins,再键入csaddins demoform levelchanged打开LevelChanged窗体。打开Mstn的层管理器,如下图所示。当您在Level Manager窗口中增加、删除层或对某层改名后,我们的LevelChanged窗体中的显示也会立即更新。您还可以通过打开另一个DGN来进一步测试,您会发现LevelChanged窗体中的内容会随着新文件的打开而改变。
下面是整个项目的源代码,供您参考。