介绍

  在ArcEngine实际开发过程中,经常会使用事件执行某项操作,比如更换地图后修改地图引用,添加图层后将添加的图层自动更新到combox控件中。本文以实例形式探讨ArcEngine事件的使用方式。主要使用的接口为IActiveViewEvents_Event接口以及AxMapControl类。

IActiveViewEvents_Event接口

  IActiveViewEvents_Event接口中包含11个事件(注意是IActiveViewEvents_Event接口不是IActiveViewEvents接口,AE中的事件接口后面都带有"_Event"),11个事件的触发条件如下:

事件 描述
AfterDraw 在指定的阶段被绘制后触发
AfterItemDraw 在绘制单个视图项后触发。示例:视图项包括地图中的图层或页面布局中的元素
ContentsChanged 当视图的内容改变时触发
ContentsCleared 视图内容被清除后触发
FocusMapChanged 激活新地图时触发
ItemAdded 将项添加到视图时触发
ItemDeleted 从视图中删除项时触发
ItemReordered 当视图项被重新排序时触发
SelectionChanged 选择集变化后触发
SpatialReferenceChanged 当空间参考改变时触发
ViewRefreshed 在绘制之前刷新视图时触发

 

  使用此接口监听与活动视图相关的特定事件,如AfterDraw和SelectionChanged。许多类实现这个接口,每个类触发不同的事件。例如,Map对象不会触发FocusMapChanged事件,而PageLayout对象会。类似地,Map对象在从Map中删除一个层时触发ItemDeleted事件,而PageLayout在删除Map Frame或图形等元素时触发相同的事件。

  注意您正在监听的特定对象的事件。例如,仅在FocusMap对象上编写侦听SelectionChanged事件的代码将不会通过更改布局视图中的选择触发事件。此外,如果FocusMap更改,则必须重置客户端。

  AfterItemDraw事件只有在IViewManager::VerboseEvents属性设置为True时才会触发。默认情况下,此属性设置为False。

示例

  本示例使用AxMapControl::OnMapReplaced事件和IActiveViewEvents_Event::ItemAdded、IActiveViewEvents_Event::ItemDeleted事件实现当主窗体中图层发生变化时,子窗体combox控件中的图层列表自动变化。

  主窗体样式及代码

 

namespace WindowsFormsApplication1
{
    public partial class FrmMain : Form
    {
        public FrmMain()
        {
            InitializeComponent();                  
        }

        private void btnChild_Click(object sender, EventArgs e)
        {
            FrmChild frm = new FrmChild(axMapControl1);
            frm.Show();
        }

        private void btnMXD_Click(object sender, EventArgs e)
        {
            ICommand cmd = new ControlsOpenDocCommand();
            cmd.OnCreate(axMapControl1.Object);
            cmd.OnClick();
        }

        private void btnAdd_Click(object sender, EventArgs e)
        {
            ICommand cmd = new ControlsAddDataCommand();
            cmd.OnCreate(axMapControl1.Object);
            cmd.OnClick();
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            if (axMapControl1.LayerCount > 0)
            {
                axMapControl1.DeleteLayer(0);
            }
        }

    }
}

 

  子窗体样式及代码

 

 

 

namespace WindowsFormsApplication1
{
    public partial class FrmChild : Form
    {        
        IActiveViewEvents_Event pEvent;
        IMapControl2 mapCon;
        AxMapControl pAxMapCon;
        public FrmChild(AxMapControl axMapCon)
        {
            InitializeComponent();
            pAxMapCon = axMapCon;         
            //注册地图更换事件
            pAxMapCon.OnMapReplaced += pAxMapCon_OnMapReplaced;

            //注册项目添加和删除事件
            mapCon = axMapCon.Object as IMapControl2;
            pEvent = mapCon.Map as IActiveViewEvents_Event;
            pEvent.ItemAdded += pEvent_ItemAdded;
            pEvent.ItemDeleted += pEvent_ItemDeleted;
        }
       
        private void pAxMapCon_OnMapReplaced(object sender, IMapControlEvents2_OnMapReplacedEvent e)
        {
            IMap pMap = e.newMap as IMap;
            pEvent = pMap as IActiveViewEvents_Event;
            pEvent.ItemAdded += pEvent_ItemAdded;
            pEvent.ItemDeleted += pEvent_ItemDeleted;
            comboBox1.Items.Clear();
            for (int i = 0; i < pMap.LayerCount; i++)
            {
                comboBox1.Items.Add(mapCon.get_Layer(i).Name);
            }
            if (comboBox1.Items.Count > 0)
            {
                comboBox1.SelectedIndex = 0;
            }
        }

        private void pEvent_ItemAdded(object Item)
        {
            ILayer pLayer = Item as ILayer;
            comboBox1.Items.Add(pLayer.Name);
            comboBox1.SelectedIndex = comboBox1.Items.Count - 1;
        }

        private void pEvent_ItemDeleted(object Item)
        {
            ILayer pLayer = Item as ILayer;
            comboBox1.Items.Remove(pLayer.Name);
            if (comboBox1.Items.Count > 0)
            {
                comboBox1.SelectedIndex = 0;
            }
            else
            {
                comboBox1.Text = "";
            }
        }
        private void FrmChild_Load(object sender, EventArgs e)
        {
            for (int i = 0; i < mapCon.LayerCount; i++)
            {
                comboBox1.Items.Add(mapCon.get_Layer(i).Name);
            }
            if (comboBox1.Items.Count > 0)
            {
                comboBox1.SelectedIndex = 0;
            }
        }
    }
}