zoukankan      html  css  js  c++  java
  • ArcGIS Engine开发-TOCControl中实现图层的拖放

      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

                    
    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)
            
    {
            }


        }


  • 相关阅读:
    超级文件夹管理器
    基于IAP和网口升级固件
    经典排序之高速排序
    hdu 4908 BestCoder Sequence
    Boost.Asio c++ 网络编程翻译(11)
    Silverlight 5 Grid组的MouseLeave响应
    Linux下实现RAID
    关于相互排斥运行的设计与实现
    Codeforces 309C Memory for Arrays 二进制模拟进位
    sharepoint 2013 资源管理器copy大文件到本地失败解决方法
  • 原文地址:https://www.cnblogs.com/watsonyin/p/504100.html
Copyright © 2011-2022 走看看