上一章我们利用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窗体中的内容会随着新文件的打开而改变。
下面是整个项目的源代码,供您参考。