TOCControl非常好,不用写一行代码就可以将整个地图的图层信息况显示出来;
  TOCControl也非常坏,提供的接口非常少,我认为有用的只有三个:HitTest,SetBuddyControl,Update,而且Update方法一执行,整个TocControl就会重新装载一次,闪烁很厉害,实在是让人烦。要想在TOCControl中拖动图层,也并不容易,得动一动脑筋才行。
  下面是我写的一个类,用于实现拖动图层,有需要的朋友,可以复制过去了,看一看。
  需要说明的是,该类需要传入一个System.Windows.Forms.Control作为移动图层时显示要移到的位置,所以,在TOCControl上最好上一个Panel,然后传入到TocHelper中。另外,在计算同m_MovingLine显示的位置时,偶没找到什么好办法,只好设置了一个行高的参数。在正常字体时,据我的经验,行高是16,在Windows大字体显示时,行高是18,可以精确的显示。但这毕竟不是一个好办法。哪位高人要是看到了这个帖子,也请指点小弟一二,感激不尽!

public class TocHelper
    {
        private ESRI.ArcGIS.TOCControl.AxTOCControl m_toc;
        private ILayer m_layer = null;
        private object m_other,m_index;

        private LayerPopmenu m_LyMenu ;
        private DataFramePopmenu m_FrameMenu = new DataFramePopmenu();

        public event CurrentLayerChangedHandler CurrentLayerChanged;

        private bool m_Dragging = false;
        private System.Windows.Forms.Control m_MovingLine;// = new System.Windows.Forms.Panel();

        public TocHelper(ESRI.ArcGIS.TOCControl.AxTOCControl toc)
        {
            m_toc = toc;
            m_LyMenu = new LayerPopmenu(this);
            m_LyMenu.TOCControl = m_toc;
            m_FrameMenu.TOCControl = m_toc;

            m_toc.LabelEdit = esriTOCControlEdit.esriTOCControlManual;
            /**////处理事件
            m_toc.OnMouseDown += new ITOCControlEvents_OnMouseDownEventHandler(m_toc_OnMouseDown);
            m_toc.OnMouseMove += new ITOCControlEvents_OnMouseMoveEventHandler(m_toc_OnMouseMove);
            m_toc.OnMouseUp += new ITOCControlEvents_OnMouseUpEventHandler(m_toc_OnMouseUp);
            m_toc.OnBeginLabelEdit += new ITOCControlEvents_OnBeginLabelEditEventHandler(m_toc_OnBeginLabelEdit);
            m_toc.OnEndLabelEdit += new ITOCControlEvents_OnEndLabelEditEventHandler(m_toc_OnEndLabelEdit);
        }

        public void SetMoveLine(System.Windows.Forms.Control line)
        {
            m_MovingLine = line;
            m_MovingLine.Size = new System.Drawing.Size(100,2);
            m_MovingLine.BackColor = System.Drawing.Color.Black;
            m_MovingLine.Visible = false;
        }

        private DevExpress.XtraBars.BarManager m_pBarManager;
        public void SetBarManager(DevExpress.XtraBars.BarManager barMan)
        {
            m_pBarManager = barMan;
            m_LyMenu.SetBarManager(barMan);
            m_FrameMenu.SetBarManager(barMan);
        }

        /**//// <summary>
        /// 获取当前图层
        /// </summary>
        public ESRI.ArcGIS.Carto.ILayer CurrentLayer
        {
            get 
            {
                return m_layer;
            }            
        }

        /**//// <summary>
        /// 刷新视图
        /// </summary>
        /// <param name="layer"></param>
        private void RefreshView(ILayer layer)
        {
            if (m_toc == null)
                return;
            if (m_toc.Buddy == null)
                return;

            IActiveView pView = null;
            if (m_toc.Buddy is  ESRI.ArcGIS.MapControl.IMapControl2)
            {
                pView = (m_toc.Buddy as ESRI.ArcGIS.MapControl.IMapControl2).ActiveView;
            }
            else if (m_toc.Buddy is ESRI.ArcGIS.SceneControl.ISceneControl)
            {
                IScene scene = (m_toc.Buddy as ESRI.ArcGIS.SceneControl.ISceneControl).Scene;
                if (scene is IActiveView)
                    pView = scene as IActiveView;
            }

            if (pView != null)
            {
                if (layer != null)
                    pView.PartialRefresh(esriViewDrawPhase.esriViewGeography,layer,pView.Extent);
                else
                    pView.Refresh();
            
            }                
        }

        private int m_DragStartY;
        public int MouseX,MouseY;
        private int m_TextHeight = 18;
        private void m_toc_OnMouseDown(object sender, ITOCControlEvents_OnMouseDownEvent e)
        {
            /**////选中对象            
            ITOCControl m_TOCControl = (ITOCControl) m_toc.Object;
            esriTOCControlItem item =esriTOCControlItem.esriTOCControlItemNone;
            ILayer layer = null;
            IBasicMap map = null;            
            m_TOCControl.HitTest(e.x,e.y,ref item,ref map,ref layer,ref m_other,ref m_index);
            MouseX = e.x;MouseY =e.y;
            m_DragStartY = e.y;

            //设置当前图层
//            if (item == esriTOCControlItem.esriTOCControlItemLayer)
//            {
                if (m_layer != layer)
                {
                    m_layer = layer;
                    if (CurrentLayerChanged != null)
                        CurrentLayerChanged();
                }
//            }
//            else
//            {
//                if (m_layer != null)
//                {
//                    m_layer = null;
//                    if (CurrentLayerChanged != null)
//                        CurrentLayerChanged();
//                }
//            }
            m_LyMenu.CurrentLayer = m_layer;
            m_FrameMenu.CurrentLayer = m_layer;

            //如果点中的图例,则弹出符号设置窗口
            if ((e.button == 1) && (item == esriTOCControlItem.esriTOCControlItemLegendClass)) 
            {
                ILegendGroup legendGroup;
                ILegendClass legendClass;
                legendGroup = m_other as ILegendGroup;
                Debug.Assert(legendGroup != null);
                legendClass = legendGroup.get_Class(Convert.ToInt32(m_index.ToString()));
                Debug.Assert(legendClass != null);
                ISymbol pSymbol = legendClass.Symbol;

                //选择符号窗口代码去掉了。
                return;

            }
            
            //如果是鼠标右键,则弹出右键菜单
            if (e.button == 2)
            {
                System.Diagnostics.Debug.Assert(m_pBarManager != null);
                if ((item == esriTOCControlItem.esriTOCControlItemLayer) && (layer != null))
                {
                    m_pBarManager.SetPopupContextMenu(m_toc,m_LyMenu.PopMenu);
                }
                else if (item == esriTOCControlItem.esriTOCControlItemMap)
                {
                    m_pBarManager.SetPopupContextMenu(m_toc,m_FrameMenu.PopMenu);
                }
                else
                {
                    m_pBarManager.SetPopupContextMenu(m_toc,null);
                }
                return;
            }

            
            //如果鼠标左键选中了一个图层,则设为拖动状态
            if ((e.button == 1) && (layer != null))
            {
                m_Dragging = true;
                m_DestLayer = null;
            }

            
            m_TextHeight = m_toc.Parent.Font.Height+2; 
            
        }

        private int GetLayerIndex(IBasicMap map,ILayer layer,bool DragUp)
        {
            ILayer tmpLayer;
            for (int i=0;i<=map.LayerCount-1;i++)
            {
                tmpLayer = map.get_Layer(i);
                if (tmpLayer == layer)
                {    
                    if (DragUp == true)
                        return i-1;
                    else
                        return i;
                }
            }
            return 0;
        }

        private int GetLayerIndex(ICompositeLayer groupLayer,ILayer layer,bool DragUp)
        {
            for (int i=0;i<=groupLayer.Count-1;i++)
            {
                if (groupLayer.get_Layer(i) == layer)
                {
                    if (i == groupLayer.Count-1)
                        return i;
                    else
                    {
                        if (DragUp == true)
                            return i;
                        else
                            return i+1;
                    }
                    
                }
            }
            return 0;
        }

        private ILayer m_DestLayer;
        private bool m_DestIsMap = false;
        private bool m_DragToCorrectPos = false;
        private void m_toc_OnMouseMove(object sender, ITOCControlEvents_OnMouseMoveEvent e)
        {
            /**////如果正在拖动图层
            if (m_Dragging == true)
            {
                m_DragToCorrectPos = false;

                ITOCControl m_TOCControl = (ITOCControl) m_toc.Object;
                esriTOCControlItem item =esriTOCControlItem.esriTOCControlItemNone;
                ILayer layer = null;
                IBasicMap map = null;
                object other = null;
                object index = null;
                m_TOCControl.HitTest(e.x,e.y,ref item,ref map,ref layer,ref other,ref index);
                
                m_DestIsMap = false;
                m_DestLayer = layer;
                if (item == esriTOCControlItem.esriTOCControlItemMap)
                {
                    m_DestIsMap = true;

                    int yy;                    
                    yy = Convert.ToInt32(Math.Floor(e.y/m_TextHeight) * m_TextHeight)+m_TextHeight;

                    m_MovingLine.Location = new System.Drawing.Point(30,yy);
                    m_MovingLine.Width = m_toc.Width - 35;
                    m_MovingLine.Visible = true;
                    m_toc.MousePointer = ESRI.ArcGIS.SystemUI.esriControlsMousePointer.esriPointerDefault;                    
                    m_DragToCorrectPos = true;
                                
                }
                else if ((item == esriTOCControlItem.esriTOCControlItemLayer) && (layer != m_layer) && (layer != null))
                
                    if (m_DestLayer is IGroupLayer)
                    {
                        m_MovingLine.Visible = false;
                        m_toc.MousePointer = ESRI.ArcGIS.SystemUI.esriControlsMousePointer.esriPointerLabel;
                        m_DragToCorrectPos = true;
                    }
                    else
                    {
                        int yy;                    
                        if (e.y > m_DragStartY)  //向下拖放
                        {
                            yy = Convert.ToInt32(Math.Floor(e.y/m_TextHeight) * m_TextHeight)+m_TextHeight;
                        }
                        else  //向上拖放
                        {
                            yy = Convert.ToInt32(Math.Floor(e.y/m_TextHeight) * m_TextHeight);                        
                        }
                        m_MovingLine.Location = new System.Drawing.Point(30,yy);
                        m_MovingLine.Width = m_toc.Width - 35;
                        m_MovingLine.Visible = true;
                        m_toc.MousePointer = ESRI.ArcGIS.SystemUI.esriControlsMousePointer.esriPointerDefault;                    
                        m_DragToCorrectPos = true;
                    }
                }
                else
                {
                    m_MovingLine.Visible = false;
                    m_toc.MousePointer = ESRI.ArcGIS.SystemUI.esriControlsMousePointer.esriPointerDefault;
                }
                
            }
        }

        /**//// <summary>
        /// 取得图层的上一级对象,可能是igrouplayer,或ibasicmap
        /// </summary>
        /// <param name="map"></param>
        /// <param name="layer"></param>
        /// <returns></returns>
        private object GetLayerParent(IBasicMap map,ILayer layer)
        {
            ILayer tmpLayer;
            for (int i=0;i<= map.LayerCount-1;i++)
            {
                tmpLayer = map.get_Layer(i);
                if (tmpLayer == layer)
                {
                    return map;
                }
                else if (tmpLayer is IGroupLayer)
                {
                    IGroupLayer ly = FindParentGroupLayer(tmpLayer as IGroupLayer,layer);
                    if (ly != null)
                        return ly;
                }
            }
            return map;
        }

        private IGroupLayer FindParentGroupLayer(IGroupLayer groupLayer,ILayer layer)
        {
            if (!(groupLayer is ICompositeLayer))
            {
                return groupLayer;
            }

            ICompositeLayer comLayer = groupLayer as ICompositeLayer;
            ILayer tmpLayer;
            for (int i=0;i<=comLayer.Count-1;i++)
            {
                tmpLayer = comLayer.get_Layer(i);
                if (tmpLayer == layer)
                    return groupLayer;
                else if (tmpLayer is IGroupLayer)
                    return FindParentGroupLayer(tmpLayer as IGroupLayer,layer);
            }
            return null;
        }

        /**//// <summary>
        /// 在grouplayer中移动图层
        /// </summary>
        /// <param name="pGroupLayer"></param>
        /// <param name="pLayer"></param>
        /// <param name="nIndex"></param>
        private void MoveLayerTo(IGroupLayer pGroupLayer, ILayer pLayer, int nIndex)
        {

            ICompositeLayer pCompositeLayer = pGroupLayer as ICompositeLayer;
//            if(pCompositeLayer.Count < 2)
//                return ;

            if(pCompositeLayer.Count-1 == nIndex)
            {
                pGroupLayer.Delete(pLayer);
                pGroupLayer.Add(pLayer);
                return;
            }

            IArray pArray = new ArrayClass();

            for(int i = 0; i < pCompositeLayer.Count; i++)
            {
                pArray.Add(pCompositeLayer.get_Layer(i));
            }

            pGroupLayer.Clear();
            ILayer pLayer1;
            for(int i = 0; i < pArray.Count; i++)
            {
                if(pCompositeLayer.Count  == nIndex)
                {
                    pGroupLayer.Add(pLayer);
                }

                pLayer1  = pArray.get_Element(i) as ILayer;
                if(pLayer1 == pLayer)
                {
                    continue;
                }
                pGroupLayer.Add(pLayer1);

            }            
        }

        private void m_toc_OnMouseUp(object sender, ITOCControlEvents_OnMouseUpEvent e)
        {
            if (m_Dragging == true)
            {
                check dragging conditions#region check dragging conditions
                m_Dragging = false;
                m_toc.MousePointer = ESRI.ArcGIS.SystemUI.esriControlsMousePointer.esriPointerDefault;
                if (m_toc == null)
                    return ;
                if (m_toc.Buddy == null)
                    return ;
                if (m_DragToCorrectPos == false)
                    return;
                m_DragToCorrectPos = false;
                m_MovingLine.Visible = false;

                IMap map=null;
                IScene scene=null;
                if (m_toc.Buddy is IMapControl2)
                {
                    map = (m_toc.Buddy as IMapControl2).Map;
                }
                else if (m_toc.Buddy is ESRI.ArcGIS.SceneControl.ISceneControl)
                {
                    scene = (m_toc.Buddy as ESRI.ArcGIS.SceneControl.ISceneControl).Scene;
                }
                else
                {
                    return;
                }

                IBasicMap bmap;
                if (map != null)
                    bmap = map as IBasicMap;
                else 
                    bmap = scene as IBasicMap;
                if (bmap.LayerCount ==0)
                    return;

                #endregion

                bool destIgnoreGroupLayer = false;
                if (m_DestIsMap == true)
                {
                    m_DestLayer = bmap.get_Layer(0);
                    destIgnoreGroupLayer = true;
                }

                if (m_DestLayer == null)
                    return;
                if (m_layer == m_DestLayer)
                    return;

                bool DragUp;  //是否正向上拖放
                DragUp = (e.y < m_DragStartY);
                int destIndex;

                object buddy = m_toc.Buddy;
                m_toc.SetBuddyControl(null);

                try
                {
                    object srcGroupLayer = GetLayerParent(bmap,m_layer);
                    object destGroupLayer = GetLayerParent(bmap,m_DestLayer);                
                
                    //先删除源图层
                    if (srcGroupLayer is GroupLayer)
                        (srcGroupLayer as IGroupLayer).Delete(m_layer);
                    else
                        bmap.DeleteLayer(m_layer);

                    //再加入,并移到合适位置
                    if ((m_DestLayer is IGroupLayer) && (destIgnoreGroupLayer == false))
                    {
                        (m_DestLayer as IGroupLayer).Add(m_layer);
                        destIndex = GetLayerIndex(m_DestLayer as ICompositeLayer,m_layer,DragUp);                    
                    
                        MoveLayerTo(m_DestLayer as IGroupLayer,m_layer,destIndex);
                        RefreshView(m_DestLayer);                                        
                    }
                    else if (destGroupLayer is IGroupLayer)
                    {                    
                        (destGroupLayer as IGroupLayer).Add(m_layer);
                        destIndex = GetLayerIndex(destGroupLayer as ICompositeLayer,m_DestLayer,DragUp);                    
                                        
                        MoveLayerTo(destGroupLayer as IGroupLayer,m_layer,destIndex);    
                        RefreshView(destGroupLayer as ILayer);
                    }
                    else
                    {
                        bmap.AddLayer(m_layer);
                        destIndex = GetLayerIndex(bmap,m_DestLayer,DragUp);
                                            
                        if (bmap is IMap)
                            (bmap as IMap).MoveLayer(m_layer,destIndex);
                        else if (bmap is IScene)
                            (bmap as IScene).MoveLayer(m_layer,destIndex);                    
                    }    
    
                }
                finally
                {
                    m_toc.SetBuddyControl(buddy);  //重新绑定,并刷新toc
                }

            }
        }

        private void m_toc_OnBeginLabelEdit(object sender, ITOCControlEvents_OnBeginLabelEditEvent e)
        {
            e.canEdit = false;
        }

        private void m_toc_OnEndLabelEdit(object sender, ITOCControlEvents_OnEndLabelEditEvent e)
        {
        }

    }

转载于:https://www.cnblogs.com/watsonyin/archive/2006/09/14/504100.html

ArcGIS Engine开发-TOCControl中实现图层的拖放相关推荐

  1. C#,ArcGIS Engine开发入门教程

    利用ArcGIS Engine.VS .NET和Windows控件开发GIS应用 Dixon整理 此过程说明适合那些使用.NET建立和部署应用的开发者,它描述了使用ArcGIS控件建立和部署应用的方法 ...

  2. ArcGIS Engine开发---图层符号化

    使用ServerStyle 如果熟悉ArcGIS Desktop的使用,就会对Style符号库文件有所了解,相对应的在ArcGIS Engine开发中对应的是ServerStyle符号库,它的结构体系 ...

  3. ArcGIS Engine开发前基础知识(2)

    ArcGIS基本控件简介 ArcGIS Engine控件是一组可视化的开发组件,每个ArcGIS Engine控件都是一个COM组件.这些组件包括MapControl,PageLayoutContro ...

  4. ArcGIS Engine开发基础总结(一)

    标准Engine功能 地图浏览    地图制作 数据查询 数据分析 及 所有的开发控件 -MapControl, PageLayout, Toolbar, TOC, ArcReader 对所有矢量和栅 ...

  5. 【转】使用ArcGIS Engine开发ArcGIS Server的胖客户端浏览程序

    摘要:在ArcGIS 9的家族中,增加了两个新产品:ArcGIS Engine和ArcGIS Server.由于它们各自分别在C/S领域和B/S领域的强大开发能力,一经推出就备受瞩目.其中ArcGIS ...

  6. GIS二次开发:实验一 ArcGIS Engine 开发初步

    实验一 ArcGIS Engine 开发初步 一.实验目的 掌握ArcGIS Engine的安装: 熟悉ArcGIS Engine中几个常用的控件: 搭建第一个简单的ArcGIS Engine 程序: ...

  7. 在 ArcGIS Engine 应用程序中加载搜狗地图和谷歌地图。

    在ArcGIS Engine 应用程序中加载搜狗地图和谷歌地图. Adding sogou map or google map in ArcGIS Engine application WebmapL ...

  8. 在ArcGIS Engine 应用程序中加载搜狗地图和谷歌地图

    在ArcGIS Engine 应用程序中加载搜狗地图和谷歌地图. Adding sogou map or google map in ArcGIS Engine application WebmapL ...

  9. ArcGIS Engine开发:框架/结构+对象库

    ArcGIS Engine开发:框架/结构+对象库 框架/结构: ArcGIS Engine 开发人员有权使用一系列的控制器,这些控制器 准许很多属性.事件和方法的使用.尽管一个简单的应用软件 仅仅通 ...

最新文章

  1. __call处理调用错误
  2. linux 下实现负载均衡群集(NAT方式)
  3. %dn在c语言中是什么意思,请问C语言中 char far 是什么意思?
  4. Impala-shell 启动异常 - Python版本为3.x 启动脚本为2.x
  5. Linux学习笔记-Makefile优化之头文件依赖
  6. 优先体验重播matlab_如何为深度Q网络实施优先体验重播
  7. 软考中级软件设计师该怎么备考
  8. signed和unsigned区别
  9. <转载>项目工程中的WebRoot与WebContent有什么区别?
  10. 注册ActiveX控件简单方法及控件未被正确授权解决方案
  11. 谷歌出品,数据集搜索引擎上线了!
  12. (七)C语言入门,代码编程,电脑关机程序【40行】【原创】
  13. iOS常用快捷键/终端常用指令
  14. 逆变器方案(高频 工频)正弦波逆变驱动开发板,完全兼容EG8010驱动板
  15. ANSYS SIWave SI仿真
  16. android 单通道多应用Push系统的设计与实现
  17. 国内十大免费网络相册
  18. 技嘉GIGABYTE AERO 15SA风扇噪音过大加油修理方法
  19. 视频采集到录制 - MP4生成
  20. vue 09 计算computed视频自学

热门文章

  1. List元素互换,List元素转换下标,Java Collections.swap()方法实例解析
  2. docker镜像的备份和恢复
  3. 写好 Python 代码的几条原则
  4. tensorflow问题
  5. i.MX6UL: i.MX 6UltraLite处理器 - 低功耗,安全,Arm® Cortex®-A7内核
  6. 算法编程Algos Programming
  7. TensorRT 7.2.1 开发概要(下)
  8. CMOS图像传感器理解
  9. 2021年大数据Flink(二十六):​​​​​​​State代码示例
  10. js函数语法:ASCII 码的相互转换,字符串操作,数学计算