AE学习日记之MapControl与PageLayoutControl图层变化同步

来源:互联网 发布:surge for mac 配置 编辑:程序博客网 时间:2024/04/30 14:18

        在许多Arcgis Engine的练习代码中,演示的MapControl 与PageLayeroutControl都是分开两次打开地图文件来实现。但是,如果这样的话,PageLayoutControl与MapControl不能同步,即当改变MapControl中的内容时无法在PageLayoutControl控件里面立即显示出来。若想要实现两者的同步,只要把两个控件的共享提个地图图层即可。具体实现过程如下:

       首先,新建一个类ControlsSynchronizer里面写入绑定的处理函数。代码示例如下:

  #region class members        private IMapControl3 m_mapControl = null;           private IPageLayoutControl2 m_pageLayoutControl = null;        private ITool m_mapActiveTool = null;        private ITool m_pageLayoutActiveTool = null;        private bool m_IsMapCtrlactive = true;        private ArrayList m_frameworkControls = null;        #endregion

定义一些成员变量,第一个IMapControl3 接口变量是用于获取对form1中的MapControl的控制。下面的 IPageLayoutControl2也同样是为了控制PageLayoutControl。第三个和第四个是为了记录mapControl 与PageLayeroutControl的活动状态,ToolbarControl 关联以上两个图层控件时需要此接口。第五个布尔型变量是为了记录当前活动的空间是否为MapControl 。第六个为一个ArrayList对象,用于存储MapControl和PageLayoutControl的Object对象。

构造函数,初始化ArrayList ,并给MapControl和PageLayoutControl 赋值。其中,自定义的构造函数中调用了默认构造函数。:this();


        #region constructor        /// <summary>        /// 默认构造函数        /// </summary>        public ControlsSynchronizer()        {            //初始化ArrayList            m_frameworkControls = new ArrayList();        }        /// <summary>        /// 构造函数        /// </summary>        /// <param name="mapControl"></param>        /// <param name="pageLayoutControl"></param>        public ControlsSynchronizer(IMapControl3 mapControl, IPageLayoutControl2 pageLayoutControl)            : this()                //调用默认构造函数        {            //为类成员赋值            m_mapControl = mapControl;            m_pageLayoutControl = pageLayoutControl;        }        #endregion

设置属性信息
        #region properties        /// <summary>        /// 取得或设置MapControl        /// </summary>        public IMapControl3 MapControl        {            get { return m_mapControl; }            set { m_mapControl = value; }        }        /// <summary>        /// 取得或设置PageLayoutControl        /// </summary>        public IPageLayoutControl2 PageLayoutControl        {            get { return m_pageLayoutControl; }            set { m_pageLayoutControl = value; }        }        /// <summary>        /// 取得当前ActiveView的类型        /// </summary>        public string ActiveViewType        {            get            {                if (m_IsMapCtrlactive)                    return "MapControl";                else                    return "PageLayoutControl";            }        }        /// <summary>        /// 取得当前活动的Control        /// </summary>        public object ActiveControl        {            get            {                if (m_mapControl == null || m_pageLayoutControl == null)                    throw new Exception("ControlsSynchronizer::ActiveControl:\r\nEither MapControl or PageLayoutControl are not initialized!");                if (m_IsMapCtrlactive)                    return m_mapControl.Object;                else                    return m_pageLayoutControl.Object;            }        }        #endregion

定义处理函数,其中包括激活MapControl 和PageLayoutControl
  #region Methods        /// <summary>        /// 激活MapControl并解除the PagleLayoutControl        /// </summary>        public void ActivateMap()        {            try            {                if (m_pageLayoutControl == null || m_mapControl == null)                    throw new Exception("ControlsSynchronizer::ActivateMap:\r\nEither MapControl or PageLayoutControl are not initialized!");                //缓存当前PageLayout的CurrentTool                if (m_pageLayoutControl.CurrentTool != null) m_pageLayoutActiveTool = m_pageLayoutControl.CurrentTool;                //解除PagleLayout                m_pageLayoutControl.ActiveView.Deactivate();                //激活MapControl                m_mapControl.ActiveView.Activate(m_mapControl.hWnd);                //将之前MapControl最后使用的tool,作为活动的tool,赋给MapControl的CurrentTool                if (m_mapActiveTool != null) m_mapControl.CurrentTool = m_mapActiveTool;                m_IsMapCtrlactive = true;                //为每一个的framework controls,设置Buddy control为MapControl                this.SetBuddies(m_mapControl.Object);            }            catch (Exception ex)            {                throw new Exception(string.Format("ControlsSynchronizer::ActivateMap:\r\n{0}", ex.Message));            }        }        /// <summary>        /// 激活PagleLayoutControl并解除MapCotrol        /// </summary>        public void ActivatePageLayout()        {            try            {                if (m_pageLayoutControl == null || m_mapControl == null)                    throw new Exception("ControlsSynchronizer::ActivatePageLayout:\r\nEither MapControl or PageLayoutControl are not initialized!");                //缓存当前MapControl的CurrentTool                if (m_mapControl.CurrentTool != null) m_mapActiveTool = m_mapControl.CurrentTool;                //解除MapControl                m_mapControl.ActiveView.Deactivate();                //激活PageLayoutControl                m_pageLayoutControl.ActiveView.Activate(m_pageLayoutControl.hWnd);                //将之前PageLayoutControl最后使用的tool,作为活动的tool,赋给PageLayoutControl的CurrentTool                if (m_pageLayoutActiveTool != null) m_pageLayoutControl.CurrentTool = m_pageLayoutActiveTool;                m_IsMapCtrlactive = false;                //为每一个的framework controls,设置Buddy control为PageLayoutControl                this.SetBuddies(m_pageLayoutControl.Object);            }            catch (Exception ex)            {                throw new Exception(string.Format("ControlsSynchronizer::ActivatePageLayout:\r\n{0}", ex.Message));            }        }        /// <summary>        /// 给予一个地图, 置换PageLayoutControl和MapControl的focus map        /// </summary>        /// <param name="newMap"></param>        public void ReplaceMap(IMap newMap)        {            if (newMap == null)                throw new Exception("ControlsSynchronizer::ReplaceMap:\r\nNew map for replacement is not initialized!");            if (m_pageLayoutControl == null || m_mapControl == null)                throw new Exception("ControlsSynchronizer::ReplaceMap:\r\nEither MapControl or PageLayoutControl are not initialized!");            //create a new instance of IMaps collection which is needed by the PageLayout            //创建一个PageLayout需要用到的,新的IMaps collection的实例            IMaps maps = new Maps();            //add the new map to the Maps collection            //把新的地图加到Maps collection里头去            maps.Add(newMap);            bool bIsMapActive = m_IsMapCtrlactive;            //call replace map on the PageLayout in order to replace the focus map            //we must call ActivatePageLayout, since it is the control we call 'ReplaceMaps'            //调用PageLayout的replace map来置换focus map            //我们必须调用ActivatePageLayout,因为它是那个我们可以调用"ReplaceMaps"的Control            this.ActivatePageLayout();            m_pageLayoutControl.PageLayout.ReplaceMaps(maps);                        //assign the new map to the MapControl            //把新的地图赋给MapControl            m_mapControl.Map = newMap;            //reset the active tools            //重设active tools            m_pageLayoutActiveTool = null;            m_mapActiveTool = null;            //make sure that the last active control is activated            //确认之前活动的control被激活            if (bIsMapActive)            {                this.ActivateMap();                m_mapControl.ActiveView.Refresh();            }            else            {                this.ActivatePageLayout();                m_pageLayoutControl.ActiveView.Refresh();            }        }        /// <summary>        /// bind the MapControl and PageLayoutControl together by assigning a new joint focus map        /// 指定共同的Map来把MapControl和PageLayoutControl绑在一起        /// </summary>        /// <param name="mapControl"></param>        /// <param name="pageLayoutControl"></param>        /// <param name="activateMapFirst">true if the MapControl supposed to be activated first,如果MapControl被首先激活,则为true</param>        public void BindControls(IMapControl3 mapControl, IPageLayoutControl2 pageLayoutControl, bool activateMapFirst)        {            if (mapControl == null || pageLayoutControl == null)                throw new Exception("ControlsSynchronizer::BindControls:\r\nEither MapControl or PageLayoutControl are not initialized!");            m_mapControl = MapControl;            m_pageLayoutControl = pageLayoutControl;            this.BindControls(activateMapFirst);        }        /// <summary>        /// bind the MapControl and PageLayoutControl together by assigning a new joint focus map        /// 指定共同的Map来把MapControl和PageLayoutControl绑在一起        /// </summary>        /// <param name="activateMapFirst">true if the MapControl supposed to be activated first,如果MapControl被首先激活,则为true</param>        public void BindControls(bool activateMapFirst)        {            if (m_pageLayoutControl == null || m_mapControl == null)                throw new Exception("ControlsSynchronizer::BindControls:\r\nEither MapControl or PageLayoutControl are not initialized!");            //create a new instance of IMap            //创造IMap的一个实例            IMap newMap = new MapClass();            newMap.Name = "Map";            //create a new instance of IMaps collection which is needed by the PageLayout            //创造一个新的IMaps collection的实例,这是PageLayout所需要的            IMaps maps = new Maps();            //add the new Map instance to the Maps collection            //把新的Map实例赋给Maps collection            maps.Add(newMap);            //call replace map on the PageLayout in order to replace the focus map            //调用PageLayout的replace map来置换focus map            m_pageLayoutControl.PageLayout.ReplaceMaps(maps);            //assign the new map to the MapControl            //把新的map赋给MapControl            m_mapControl.Map = newMap;            //reset the active tools            //重设active tools            m_pageLayoutActiveTool = null;            m_mapActiveTool = null;            //make sure that the last active control is activated            //确定最后活动的control被激活            if (activateMapFirst)                this.ActivateMap();            else                this.ActivatePageLayout();        }        /// <summary>        ///by passing the application's toolbars and TOC to the synchronization class, it saves you the        ///management of the buddy control each time the active control changes. This method ads the framework        ///control to an array; once the active control changes, the class iterates through the array and         ///calles SetBuddyControl on each of the stored framework control.        /// </summary>        /// <param name="control"></param>        public void AddFrameworkControl(object control)        {            if (control == null)                throw new Exception("ControlsSynchronizer::AddFrameworkControl:\r\nAdded control is not initialized!");            m_frameworkControls.Add(control);        }        /// <summary>        /// Remove a framework control from the managed list of controls        /// </summary>        /// <param name="control"></param>        public void RemoveFrameworkControl(object control)        {            if (control == null)                throw new Exception("ControlsSynchronizer::RemoveFrameworkControl:\r\nControl to be removed is not initialized!");            m_frameworkControls.Remove(control);        }        /// <summary>        /// Remove a framework control from the managed list of controls by specifying its index in the list        /// </summary>        /// <param name="index"></param>        public void RemoveFrameworkControlAt(int index)        {            if (m_frameworkControls.Count < index)                throw new Exception("ControlsSynchronizer::RemoveFrameworkControlAt:\r\nIndex is out of range!");            m_frameworkControls.RemoveAt(index);        }        /// <summary>        /// when the active control changes, the class iterates through the array of the framework controls        ///  and calles SetBuddyControl on each of the controls.        /// </summary>        /// <param name="buddy">the active control</param>        private void SetBuddies(object buddy)        {            try            {                if (buddy == null)                    throw new Exception("ControlsSynchronizer::SetBuddies:\r\nTarget Buddy Control is not initialized!");                foreach (object obj in m_frameworkControls)                {                    if (obj is IToolbarControl)                    {                        ((IToolbarControl)obj).SetBuddyControl(buddy);                    }                    else if (obj is ITOCControl)                    {                        ((ITOCControl)obj).SetBuddyControl(buddy);                    }                }            }            catch (Exception ex)            {                throw new Exception(string.Format("ControlsSynchronizer::SetBuddies:\r\n{0}", ex.Message));            }        }        #endregion

其中,给PageLayoutControl进行赋值时使用了一个自定义的Maps类来对IMAP接口进行初始化,Maps类的定义如下:

 public class Maps : IMaps, IDisposable    {        //class member - using internally an ArrayList to manage the Maps collection        private ArrayList m_array = null;        #region class constructor        public Maps()        {            m_array = new ArrayList();        }        #endregion        #region IDisposable Members        /// <summary>        /// Dispose the collection        /// </summary>        public void Dispose()        {            if (m_array != null)            {                m_array.Clear();                m_array = null;            }        }        #endregion        #region IMaps Members        /// <summary>        /// Remove the Map at the given index        /// </summary>        /// <param name="Index"></param>        public void RemoveAt(int Index)        {            if (Index > m_array.Count || Index < 0)                throw new Exception("Maps::RemoveAt:\r\nIndex is out of range!");            m_array.RemoveAt(Index);        }        /// <summary>        /// Reset the Maps array        /// </summary>        public void Reset()        {            m_array.Clear();        }        /// <summary>        /// Get the number of Maps in the collection        /// </summary>        public int Count        {            get            {                return m_array.Count;            }        }        /// <summary>        /// Return the Map at the given index        /// </summary>        /// <param name="Index"></param>        /// <returns></returns>        public IMap get_Item(int Index)        {            if (Index > m_array.Count || Index < 0)                throw new Exception("Maps::get_Item:\r\nIndex is out of range!");            return m_array[Index] as IMap;        }        /// <summary>        /// Remove the instance of the given Map        /// </summary>        /// <param name="Map"></param>        public void Remove(IMap Map)        {            m_array.Remove(Map);        }        /// <summary>        /// Create a new Map, add it to the collection and return it to the caller        /// </summary>        /// <returns></returns>        public IMap Create()        {            IMap newMap = new MapClass();            m_array.Add(newMap);            return newMap;        }        /// <summary>        /// Add the given Map to the collection        /// </summary>        /// <param name="Map"></param>        public void Add(IMap Map)        {            if (Map == null)                throw new Exception("Maps::Add:\r\nNew Map is mot initialized!");            m_array.Add(Map);        }        #endregion    }



由于绑定MapControl 与PageLayeroutControl,在打开文件的代码函数时就需要对其进行绑定。因此需要重写一个打开文件的函数,如下:

 public override void OnClick()        {            // TODO: Add OpenNewMapDocument.OnClick implementation            OpenFileDialog dlg = new OpenFileDialog();            dlg.Filter = "Map Documents (*.mxd)|*.mxd";            dlg.Multiselect = false;            dlg.Title = "Open Map Document";            if (dlg.ShowDialog() == DialogResult.OK)            {                string docName = dlg.FileName;                IMapDocument mapDoc = new MapDocumentClass();                if (mapDoc.get_IsPresent(docName) && !mapDoc.get_IsPasswordProtected(docName))                {                    mapDoc.Open(docName, string.Empty);                    IMap map = mapDoc.get_Map(0);                    m_controlsSynchronizer.ReplaceMap(map);                    mapDoc.Close();                }            }        }

        在上面函数中,打开地图文件以后。将map传入ReplaceMap函数中,用于初始化控件地图。

当以上函数定义完以后,就需要在form1的Lord函数中对其初始化。代码如下:

 m_mapControl = (IMapControl3)this.axMapControl1.Object;            m_pageLayoutControl = (IPageLayoutControl2)this.axPageLayoutControl1.Object;            //初始化controls synchronization calss            m_controlsSynchronizer = new            ControlsSynchronizer(m_mapControl, m_pageLayoutControl);            //把MapControl和PageLayoutControl绑定起来(两个都指向同一个Map),然后设置MapControl为活动的Control            m_controlsSynchronizer.BindControls(true);            //为了在切换MapControl和PageLayoutControl视图同步,要添加Framework Control            m_controlsSynchronizer.AddFrameworkControl(axToolbarControl1.Object);            m_controlsSynchronizer.AddFrameworkControl(this.axTOCControl1.Object);            // 添加打开命令按钮到工具条            OpenNewMapDocument openMapDoc = new OpenNewMapDocument(m_controlsSynchronizer);            axToolbarControl1.AddItem(openMapDoc, -1, 0, false, -1, esriCommandStyles.esriCommandStyleIconOnly);


------------------------------------------------------------------------------------end-----------------------------------------------------------


0 0
原创粉丝点击