ArcEngine在MapControl中使用符号选择器(Symbol Selector)
在ArcEngine中使用符号选择器一般有两种方式,一种是直接调用ArcMap的ISymbolSelector接口;一种是自定义实现。两种方式网上资源都很多,可以自行查找。本文主要讲符号选择器在MapControl中的使用(网上大部分资源都是在Toccontrol中使用)。其本质就是就是怎么获取LegendClass的问题
1.在TocControl中使用(也是使用方式最多的一种)
首先需要在TOCControl的鼠标单击或者双击事件中调用HitTest方法捕捉相应图层的LegendClass,这种方法是通过ArcEngine的TocControl获取LegendClass。方法如下:
public void HitTest ( int X, int Y, ref esriTOCControlItem ItemType, ref IBasicMap BasicMap, ref ILayerLayer, ref object Unk, ref object Data );
其中参数意义如下:
- X,Y :鼠标点击的坐标;
- ITemType: esriTOCControlItem枚举常量
- BasicMap:绑定MapControl的IBasicMap接口
- Layer:被点击的图层
- Unk:TOCControl的LegendGroup对象
- Data:LegendClass在LegendGroup中的Index
常用的代码如下:
private void TOCLayer_OnDoubleClick(object sender, ITOCControlEvents_OnDoubleClickEvent e)
{
if (e.button != 1)
{
return;
}
esriTOCControlItem itemType = esriTOCControlItem.esriTOCControlItemNone;
IBasicMap pBasicMap = null;
ILayer pLayer = null;
object unk = null;
object data = null;
TOCLayer.HitTest(e.x, e.y, ref itemType, ref pBasicMap, ref pLayer, ref unk, ref data);
if (e.button == 1)
{
if (itemType == esriTOCControlItem.esriTOCControlItemLegendClass)
{
ILegendClass pLegendClass = ((ILegendGroup)unk).get_Class((int)data);
FrmSymbolSelect SymbolSelectorFrm = new FrmSymbolSelect(pLegendClass, pLayer);
if (SymbolSelectorFrm.ShowDialog() == DialogResult.OK)
{
m_MapMain.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, null);
pLegendClass.Symbol = SymbolSelectorFrm.pSymbol;
m_MapMain.ActiveView.Refresh();
TOCLayer.Refresh();
}
}
}
}
2.自定义目录树,不用TOCControl控件
有时不想用ArcEngine的TocControl,想要使用自定义的目录树,但同样需要获取LengendClass,此时不能用TocControl的HitTest方法了。此时可以使用可以通过LegendInfo来获取:
参考博客:博客
IFeatureLayer pFeatureLayer = treeFrame.SelectedNode.Tag as IFeatureLayer;
ILegendInfo li = (ILegendInfo)pFeatureLayer;
ILegendGroup lg = li.get_LegendGroup(0);
SymbolSelectorFrm frm = new SymbolSelectorFrm(pLegend, pFeatureLayer);
3.既不使用Toccontrol,也不使用目录树,直接利用图层(layer)来使用
有时候自己不想使用Toccontrol,也不使用自定义目录树,只想在MapControl的的右键菜单中使用,或者把符号选择器做到ToolBar中使用,那么咱们通过一个图层来操作呢?其实质就是通过图层(layer)获取LengendClass,这里面用到了一些列的接口查询(QI),用到的接口有IFeatureLayer、ILegendInfo 、ILegendGroup、ILegendClass,本质和自定义目录树是一样的。
关键代码如下:
ILayer pLayer = this.MapFrom.get_Layer(0);
//中间通过一系列的接口查询把ILayer转为ILegendClass
IFeatureLayer pFeatureLayer = pLayer as IFeatureLayer;
ILegendInfo lengendInfo = (ILegendInfo)pFeatureLayer;
ILegendGroup legendGroup = lengendInfo.get_LegendGroup(0);
ILegendClass pLegendClass = legendGroup.get_Class(0); //获取到LegendClass
FrmSymbolSelect SymbolSelectorFrm = new FrmSymbolSelect(pLegendClass, pLayer);
if (SymbolSelectorFrm.ShowDialog() == DialogResult.OK)
{
MapFrom.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, null);
pLegendClass.Symbol = SymbolSelectorFrm.pSymbol;
MapFrom.ActiveView.Refresh();
}
我这里是自定义符号选择器,然后不使用Toccontrol,也不使用目录树,直接利用图层(layer),并做成了ToolBar的样式,最终的效果图如下所示: