第一步:建立独立的 Windows 窗体:命名为:SymbologyFrmLee
1. 运行效果如下所示:
2. 全局参数:
esriSymbologyStyleClass pStyleClass; //获取显示的为点类、线类还是填充类等的,赋值给 symbologyControl 控件,然后就显示这一类符号 public IStyleGalleryItem pStyleGalleryItem; //获取选择的项 ILegendClass pLegendClass; //获取传递进来的图例 ILayer pLayer; bool contextMenuMoreSymbolInitiated = false; //判断右键菜单是否已经初始化了
3. 给窗体添加参数:
public SymbologyFrmLee(ILegendClass tempLegendClass, ILayer tempLayer) { InitializeComponent(); pLegendClass = tempLegendClass; //通过点击 toccontrol 时候可以获得要素类的 LegendClass! pLayer = tempLayer; //点击的图层 }
4. 窗体加载事件:
private void SymbologyFrm_Load(object sender, EventArgs e) { switch(((IFeatureLayer)pLayer).FeatureClass.ShapeType) //判断图层中要素类的图形类型,不同类型显示的调节值的控件不同 { case esriGeometryType.esriGeometryPoint: //点 pStyleClass = esriSymbologyStyleClass.esriStyleClassMarkerSymbols; lbColor.Visible = true; lbWidth.Visible = true; lbWidth.Text = "符号大小"; lbAngle.Visible = true; btColor.Visible = true; nudWidth.Visible = true; cbColor.Visible = true; nudAngle.Visible = true; break; case esriGeometryType.esriGeometryPolyline: //线 pStyleClass = esriSymbologyStyleClass.esriStyleClassLineSymbols; lbColor.Visible = true; lbColor.Location = System.Drawing.Point.Add(lbColor.Location, new Size(0, 12)); lbWidth.Visible = true; lbWidth.Location = System.Drawing.Point.Add(lbWidth.Location, new Size(0, 24)); lbWidth.Text = "线符号粗细"; btColor.Visible = true; cbColor.Visible = true; btColor.Location = System.Drawing.Point.Add(btColor.Location, new Size(0, 12)); cbColor.Location = System.Drawing.Point.Add(cbColor.Location, new Size(0, 12)); nudWidth.Visible = true; nudWidth.Location = System.Drawing.Point.Add(nudWidth.Location, new Size(0, 24)); break; case esriGeometryType.esriGeometryPolygon: //面 pStyleClass = esriSymbologyStyleClass.esriStyleClassFillSymbols; lbColor.Visible = true; lbWidth.Visible = true; lbWidth.Text = "框线宽度"; lbOutlineColor.Visible = true; btColor.Visible = true; btOutlineColor.Visible = true; nudWidth.Visible = true; cbColor.Visible = true; cbOutlineColor.Visible = true; break; default: this.Close(); break; } string strInstall = @"C:\Program Files (x86)\ArcGIS"; //安装目录,10中可以用函数获得 RuntimeManager 可以获取!
//ESRI.ArcGIS.RuntimeManager.ActiveRuntime.Path 可以获得 Engine 的安装目录 string stylePath = strInstall + @"\Styles\ESRI.ServerStyle"; //获取 ESRI.ServerStyle 文件 axSymbologyControl1.LoadStyleFile(stylePath); //加载此文件 axSymbologyControl1.StyleClass = pStyleClass; //将上面获得的 pStyleClass 赋值过去,显示点、线还是面,由此决定! IStyleGalleryItem pCurrentStyleGalleryItem = new StyleGalleryItem(); //新建当前符号的实例 pCurrentStyleGalleryItem.Name = "当前符号"; pCurrentStyleGalleryItem.Item = pLegendClass.Symbol; //将当前的图例 symbol 赋值过去 ISymbologyStyleClass pSymbologyStyleClass = axSymbologyControl1.GetStyleClass(axSymbologyControl1.StyleClass); //QI,加入这个新建项 pSymbologyStyleClass.AddItem(pCurrentStyleGalleryItem, 0); pSymbologyStyleClass.SelectItem(0); //同时选中 }
5. 选择项的时候触发:
private void axSymbologyControl1_OnItemSelected(object sender, ISymbologyControlEvents_OnItemSelectedEvent e) { pStyleGalleryItem = e.styleGalleryItem as IStyleGalleryItem; //获取选择项 PreviewPicture(); //在图片框中显示 if (((IFeatureLayer)pLayer).FeatureClass.ShapeType == esriGeometryType.esriGeometryPoint) //点,将属性传递到调节的控件上 { IRgbColor pColor = ((IMarkerSymbol)pStyleGalleryItem.Item).Color as IRgbColor; btColor.BackColor = Color.FromArgb(pColor.Red, pColor.Green, pColor.Blue); //赋值颜色 nudAngle.Value = Convert.ToDecimal(((IMarkerSymbol)pStyleGalleryItem.Item).Angle); //赋值角度 nudWidth.Value = Convert.ToDecimal(((IMarkerSymbol)pStyleGalleryItem.Item).Size); //赋值大小 } if (((IFeatureLayer)pLayer).FeatureClass.ShapeType == esriGeometryType.esriGeometryPolyline) //线 { IRgbColor pColor = ((ILineSymbol)pStyleGalleryItem.Item).Color as IRgbColor; btColor.BackColor = Color.FromArgb(pColor.Red, pColor.Green, pColor.Blue); //赋值线的颜色 nudWidth.Value = Convert.ToDecimal(((ILineSymbol)pStyleGalleryItem.Item).Width); //赋值线的宽度 } if (((IFeatureLayer)pLayer).FeatureClass.ShapeType == esriGeometryType.esriGeometryPolygon) //面 { IRgbColor pColor = ((IFillSymbol)pStyleGalleryItem.Item).Color as IRgbColor; btColor.BackColor = Color.FromArgb(pColor.Red, pColor.Green, pColor.Blue); //赋值填充的颜色 nudWidth.Value = Convert.ToDecimal(((IFillSymbol)pStyleGalleryItem.Item).Outline.Width); //赋值边框宽度 pColor = ((IFillSymbol)pStyleGalleryItem.Item).Outline.Color as IRgbColor; btOutlineColor.BackColor = Color.FromArgb(pColor.Red, pColor.Green, pColor.Blue); //赋值边框颜色 } }
6. 将 pStyleGalleryItem 反映到 picture 上的方法:
private void PreviewPicture() { ISymbologyStyleClass pSymbologyStyle = axSymbologyControl1.GetStyleClass(axSymbologyControl1.StyleClass); //因为其有方法 PreviewStyle stdole.IPictureDisp picture = pSymbologyStyle.PreviewItem(pStyleGalleryItem, pictureBox1.Width, pictureBox1.Height); //建立实例 Image image = Image.FromHbitmap(new IntPtr(picture.Handle)); //转成 C# 支持的 Image 实例 pictureBox1.Image = image; //赋值过去 }
▲ 将控件的操作操作反映到 picture 上:
7. 点、线、面填充颜色传递:
IRgbColor pColor = new RgbColor(); //颜色实例 pColor.RGB = 255; tagRECT pTag = new tagRECT(); //用于下面显示 ColorPalette 的位置 pTag.left = btColor.PointToScreen(System.Drawing.Point.Empty).X; //按钮控件的左边全局横坐标 pTag.bottom = btColor.PointToScreen(System.Drawing.Point.Empty).Y + btColor.Height; //按钮控件的下边全局纵坐标 IColorPalette pColorPalette = new ColorPalette(); pColorPalette.TrackPopupMenu(ref pTag, pColor, false, 0); //显示 ColorPalette pColor = pColorPalette.Color as IRgbColor; //获取选中的颜色 Color color = Color.FromArgb(pColor.Red, pColor.Green, pColor.Blue); //将颜色转为 C# 颜色 btColor.BackColor = color; switch (((IFeatureLayer)pLayer).FeatureClass.ShapeType) //判断几何体样式 { case esriGeometryType.esriGeometryPoint: //点 ((IMarkerSymbol)pStyleGalleryItem.Item).Color = pColor; //转为 IMarkerSymbol,注意改好后要在图片上显示 PreviewPicture(); break; case esriGeometryType.esriGeometryPolyline: //线 ((ILineSymbol)pStyleGalleryItem.Item).Color = pColor; //转为 ILineSymbol PreviewPicture(); break; case esriGeometryType.esriGeometryPolygon: //面 ((IFillSymbol)pStyleGalleryItem.Item).Color = pColor; //转为 IFillSymbol PreviewPicture(); break; default: break; }
8. 点的大小、线的宽度、填充边框宽度传递:
switch (((IFeatureLayer)pLayer).FeatureClass.ShapeType) { case esriGeometryType.esriGeometryPoint: ((IMarkerSymbol)pStyleGalleryItem.Item).Size = Convert.ToDouble(nudWidth.Value); //点的大小,注意改后要在图片上显示 PreviewPicture(); break; case esriGeometryType.esriGeometryPolyline: ((ILineSymbol)pStyleGalleryItem.Item).Width = Convert.ToDouble(nudWidth.Value); //线的宽度 PreviewPicture(); break; case esriGeometryType.esriGeometryPolygon: ILineSymbol pLineSymbol = ((IFillSymbol)pStyleGalleryItem.Item).Outline; //实例化一个 linesymbol 然后赋值过去,直接赋值的话没有反应 pLineSymbol.Width = Convert.ToDouble(nudWidth.Value); //赋值 ((IFillSymbol)pStyleGalleryItem.Item).Outline = pLineSymbol; //在赋值给填充的外框 PreviewPicture(); break; default: break; }
9. 填充外边框颜色的传递:
IRgbColor pColor = new RgbColor(); pColor.RGB = 255; tagRECT ptagRECT = new tagRECT(); ptagRECT.left = btOutlineColor.PointToScreen(System.Drawing.Point.Empty).X; ptagRECT.bottom = btOutlineColor.PointToScreen(System.Drawing.Point.Empty).Y + btOutlineColor.Height; IColorPalette pColorPalette = new ColorPalette(); pColorPalette.TrackPopupMenu(ref ptagRECT, pColor, false, 0); pColor = pColorPalette.Color as IRgbColor; btOutlineColor.BackColor = Color.FromArgb(pColor.Red, pColor.Green, pColor.Blue); ILineSymbol pLineSymbol = ((IFillSymbol)pStyleGalleryItem.Item).Outline; pLineSymbol.Color = pColor; ((IFillSymbol)pStyleGalleryItem.Item).Outline = pLineSymbol; PreviewPicture();
颜色显示效果如下:
10. 点的角度实现如下:
((IMarkerSymbol)pStyleGalleryItem.Item).Angle = Convert.ToDouble(nudAngle.Value);
PreviewPicture();
11. 更多符号的实现:
private void btMore_Click(object sender, EventArgs e) { if (contextMenuMoreSymbolInitiated == false) //如果没有初始化,则首先初始化 { string stylePath = @"C:\Program Files (x86)\ArcGIS\Styles"; //获取 styles 文件夹,并将里面 *.ServerStyle 文件赋值到数组中,用于加载 string[] strFiles = Directory.GetFiles(stylePath, "*.ServerStyle"); ToolStripMenuItem[] symbolContextMenuItem = new ToolStripMenuItem[strFiles.Length + 1]; //定义菜单项,最后一个为另类 for (int i = 0; i < strFiles.Length; i++) { symbolContextMenuItem[i] = new ToolStripMenuItem(); //首先新建,然后允许选中时是否有 checked 变化 symbolContextMenuItem[i].CheckOnClick = true; symbolContextMenuItem[i].Text = System.IO.Path.GetFileNameWithoutExtension(strFiles[i]); //将名字赋值给 text 属性,完整地址赋值给 name,便于加载 if (symbolContextMenuItem[i].Text == "ESRI") symbolContextMenuItem[i].Checked = true; //默认是加载的这个文件,所以默认选中 symbolContextMenuItem[i].Name = strFiles[i]; } symbolContextMenuItem[strFiles.Length] = new ToolStripMenuItem(); //最后一个菜单项 symbolContextMenuItem[strFiles.Length].Text = "更多工具"; symbolContextMenuItem[strFiles.Length].Name = "AddMoreSymbol";
contextMenuStrip1.Items.AddRange(symbolContextMenuItem); //将菜单项添加到右键菜单中 contextMenuMoreSymbolInitiated = true; //将此值赋值为 true,以便之后不用执行这一部分了 } contextMenuStrip1.Show(btMore.Location); //弹出右键菜单 }
12. 点击右键菜单:
private void contextMenuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e) { ToolStripMenuItem pToolStripMenuItem = e.ClickedItem as ToolStripMenuItem; //首先获取点击项 if (pToolStripMenuItem.Name == "AddMoreSymbol") //最后一项,打开对话框,浏览想要打开的文件 { if (openFileDialog1.ShowDialog() == DialogResult.OK) { axSymbologyControl1.LoadStyleFile(openFileDialog1.FileName); axSymbologyControl1.Refresh(); } } else //其他项 { if (pToolStripMenuItem.Checked == false) //之前若是没有选中的,则加载,同时也就选中了 { axSymbologyControl1.LoadStyleFile(pToolStripMenuItem.Name); axSymbologyControl1.Refresh(); } else //之前若是选中的,现在就要删除,同时也就不再选中了 { axSymbologyControl1.RemoveFile(pToolStripMenuItem.Name); axSymbologyControl1.Refresh(); } } }
第二步在主窗体调用此符号窗体:
private void axTOCControl1_OnMouseDown(object sender, ITOCControlEvents_OnMouseDownEvent e) { esriTOCControlItem item = esriTOCControlItem.esriTOCControlItemNone; IBasicMap map = null; ILayer layer = null; object other = null; object index = null; axTOCControl1.HitTest(e.x, e.y, ref item, ref map, ref layer, ref other, ref index); //获取足够的图层和图例信息
if (e.button == 1) //点击左键的时候触发 { ILegendClass pLegend = new LegendClassClass(); //首先获取图例,然后赋值过去 ISymbol symbol = null; //新建 symbol,从符号窗体中最后就是获得这个东西 if (other is ILegendGroup && (int)index != -1) pLegend = ((ILegendGroup)other).get_Class((int)index) as ILegendClass; //给上面建的图例类赋值 SymbologyFrmLee frm = new SymbologyFrmLee(pLegend, layer); //新建符号窗体,并将该赋值的赋值过去 frm.ShowDialog(); //显示对话框,之后就获得了 symbol 了 symbol = frm.pStyleGalleryItem.Item as ISymbol; //调用窗体的 public 字段 pLegend.Symbol = symbol; //将 symbol 赋值给图例 axMapControl1.Refresh(esriViewDrawPhase.esriViewGeography, null, null); //刷新地图 } }