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的樣式,最終的效果圖如下所示: