全国高分辨率土地利用数据服务 土地利用数据服务 土地覆盖数据服务 坡度数据服务 土壤侵蚀数据服务 全国各省市DEM数据服务 耕地资源空间分布数据服务 草地资源空间分布数据服务 林地资源空间分布数据服务 水域资源空间分布数据服务 建设用地空间分布数据服务 地形、地貌、土壤数据服务 分坡度耕地数据服务 全国大宗农作物种植范围空间分布数据服务
多种卫星遥感数据反演植被覆盖度数据服务 地表反照率数据服务 比辐射率数据服务 地表温度数据服务 地表蒸腾与蒸散数据服务 归一化植被指数数据服务 叶面积指数数据服务 净初级生产力数据服务 净生态系统生产力数据服务 生态系统总初级生产力数据服务 生态系统类型分布数据服务 土壤类型质地养分数据服务 生态系统空间分布数据服务 增强型植被指数数据服务
多年平均气温空间分布数据服务 多年平均降水量空间分布数据服务 湿润指数数据服务 大于0℃积温空间分布数据服务 光合有效辐射分量数据服务 显热/潜热信息数据服务 波文比信息数据服务 地表净辐射通量数据服务 光合有效辐射数据服务 温度带分区数据服务 山区小气候因子精细数据服务
全国夜间灯光指数数据服务 全国GDP公里格网数据服务 全国建筑物总面积公里格网数据服务 全国人口密度数据服务 全国县级医院分布数据服务 人口调查空间分布数据服务 收入统计空间分布数据服务 矿山面积统计及分布数据服务 载畜量及空间分布数据服务 农作物种植面积统计数据服务 农田分类面积统计数据服务 农作物长势遥感监测数据服务 医疗资源统计数据服务 教育资源统计数据服务 行政辖区信息数据服务
Landsat 8 高分二号 高分一号 SPOT-6卫星影像 法国Pleiades高分卫星 资源三号卫星 风云3号 中巴资源卫星 NOAA/AVHRR MODIS Landsat TM 环境小卫星 Landsat MSS 天绘一号卫星影像
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#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)
{
}
}