TOCControl控件相当于ArcMap中左侧的目录树,需要与一个“伙伴控件”协同工作,可以是MapControl、PageLayoutControl、SceneControl或者GlobeControl。伙伴控件的设置可通过TOCControl属性对话框或用SetBuddyControl方法通过编程设置。fangfa
HitTest方法用来获取用户再TOCControl中点击的相关信息
public void HitTest(int X,int Y,ref esriTOCControlItem ItemType,ref IBasicMap BasicMap,ref ILayer,ref object Unk,ref object Data);
ItemType:TOCControl中项的类型,如none、map、layer、heading、或者legend class。
BasicMap:IMap对象。
Layer:ILayer对象。
Unk:ILegendGroup(图例组,一个图层可以有多种符号化方案)对象。
Data:用户点击的图例组中某个图例的索引号(longInt);联合使用图例组Unk和某个索引号,可以获得用户点击的图例;图例的标题头索引为-1。
图层符号选择器的实现
调用ArcMap的符号选择器
此种方法的前提是电脑上必须安装ArcGIS Desktop,该方法写在axTOCControl控件的双击事件下:
private void axTOCControl1_OnDoubleClick(object sender, ITOCControlEvents_OnDoubleClickEvent e)
{
esriTOCControlItem toccItem = esriTOCControlItem.esriTOCControlItemNone;
ILayer layer = null; IBasicMap basicMap = null; object unk = null; object data = null;//定义HitTest函数所需的参数
if(e.button==1)
{
axTOCControl1.HitTest(e.x, e.y,ref toccItem, ref basicMap, ref layer, ref unk, ref data);
{
ESRI.ArcGIS.Carto.ILegendClass pLC = new LegendClassClass();//用户点击的图例
ESRI.ArcGIS.Carto.ILegendGroup PLG = new LegendGroupClass();//用户点击的图例组
if(unk is ILegendGroup)
{
PLG = (ILegendGroup)unk;
}//获取图例组
pLC=PLG.Class[(int)data];//获取图例组中点击的具体图例
ISymbol pSym;
pSym = pLC.Symbol;
ISymbolSelector pSS = new SymbolSelectorClass();//实例化符号选择器
bool bOK = false;
pSS.AddSymbol(pSym);//添加符号的目录
bOK = pSS.SelectSymbol(0);
if(bOK)
{
pLC.Symbol = pSS.GetSymbolAt(0);//利用0索引检索选中的符号
}
this.axMapControl1.ActiveView.Refresh();
this.axTOCControl1.Refresh();
}
}
}
ISymbolSelector涉及到的方法说明:
AddSymbol:决定符号选择器出现时显示的初始符号,例如双击的是面符号,出现的界面也是面界面。
GetSymbolAt:通过0索引检索符号。
SelectSymbol:选择符号,检查用户点击确定或取消的返回值。
效果图如下:
自定义符号选择器
如果并未安装arcgis desktop又想实现该功能,可以自定义界面来实现:
界面设计如下:
窗体及控件的属性设置见下表:
[tr]控件NAMETEXT其它属性设置[/tr]FormGetSymbolByControlForm符号选择器
AxSymbologyControlaxSymbologyControl1––
groupBoxgroupBox1预览
groupBoxgroupBox2设置–
pictureBoxpictureBox1Dock设置为fill
Labell_color颜色–
Labell_size大小-
Labell_width宽度-
Labell_angel角度-
Labell_cofout外框颜色-
buttonb_color--
buttonb_cofout--
numericUpDownn_size--
numericUpDownn_width--
numericUpDownn_angle--
buttonb_more更多符号-
buttonb_color确定DialogResult属性设为OK
buttonb_color取消-
openFileDialogopenFileDialog1-Filter属性设置为:Styles 文件/*.ServerStyle
ContextMenuStripContextMenur--
ColorDialogcolorDialog--
该事件仍旧写在图例双击里:
代码的基本流程如下:
获取图层组和图层
初始化SymbologyControl的StyleClass
根据图层类型为SymbologyControl导入相应的符号样式文件
取得选定的符号
在GetSymbolByControlForm窗体中使用到的全局变量有:
private IStyleGalleryItem pStyleGalleryItem;//每一个style文件由IStyleGalleryItems组成
private ILegendClass pLegendClass;//图例组
private ILayer pLayer;//具体图层
public ISymbol pSymbol;//符号
public Image pSymbolImage;//用于预览符号
bool contextMenuMoreSymbolInitiated = false;
通过改变GetSymbolByControlForm的参数实现两个窗口之间传值,代码如下:
public GetSymbolByControlForm(ILegendClass legendClass,ILayer layer)
{
InitializeComponent();
this.pLegendClass = legendClass;//传入选择图例
this.pLayer = layer;//传入选中图层
}
初始化SymbologyControl的StyleClass,图层如果已有符号,则把符号添加到SymbologyControl中的第一个符号,并选中
private void SetFeatureClassStyle(esriSymbologyStyleClass symbologyStyleClass)
{
this.axSymbologyControl1.StyleClass = symbologyStyleClass;
ISymbologyStyleClass PsymbologyStyleClass = this.axSymbologyControl1.GetStyleClass(symbologyStyleClass);
if(this.pLegendClass!=null)
{
IStyleGalleryItem styleGalleryItem = new ServerStyleGalleryItem();
styleGalleryItem.Name = “当前符号”;
styleGalleryItem.Item = pLegendClass.Symbol;
PsymbologyStyleClass.AddItem(styleGalleryItem, 0);
this.pStyleGalleryItem = styleGalleryItem;
}/如果传入的图例不为空,则将其加入至styleGalleryItem中的第一个,默认选中
PsymbologyStyleClass.SelectItem(0);//传入图例为空,则默认选中第一个
}
载入ESRI.ServerStyle文件到SymbologyControl有两种方法:第一种方法是从注册表读取arcgis的安装路径,再使用axSymbologyControl1的LoadDesktopStyleFile()方法载入;也可以在axSymbologyControl1的属性中设置。
方法一:
读取注册表的函数(后文无用)
private string ReadRegistry(string sKey)
{
RegistryKey localMachine = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32);
string InstallDir = string.Empty;
Microsoft.Win32.RegistryKey rk = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(sKey, true);
if (rk == null)
return “”;
return (string)rk.GetValue(InstallDir);
}
2.直接设置(右键属性,Style Files,load~):
在GetSymbolByControlForm窗体的load函数中代码如下(该程序中我采用的是设置属性的方法)
private void GetSymbolByControlForm_Load(object sender, EventArgs e)
{
string sInstall = ESRI.ArcGIS.RuntimeManager.ActiveRuntime.Path;//这也是获取安装路径的一种方法
// string sInstall = ReadRegistry(“SOFTWARE\ESRI\Desktop10.2”);//获取ArcGIS安装路径
// this.axSymbologyControl1.LoadDesktopStyleFile(sInstall + “\Styles\ESRI.ServerStyle”);//载入ESRI.ServerStyle文件到SymbologyControl
IGeoFeatureLayer pGeoFeatureLayer = (IGeoFeatureLayer)pLayer;
switch(((IFeatureLayer)pLayer).FeatureClass.ShapeType)//确定图层的类型,设置空间按的StyleClass,设置各控件的可见性
{
case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint:
this.SetFeatureClassStyle(esriSymbologyStyleClass.esriStyleClassMarkerSymbols);//如果是点要素
this.l_angel.Visible = true;
this.n_angle.Visible = true;
this.l_size.Visible = true;
this.n_size.Visible = true;
this.l_width.Visible = false;
this.n_width.Visible = false;
this.l_cofout.Visible = false;
this.b_cofout.Visible = false;
break;
case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolygon:
this.SetFeatureClassStyle(esriSymbologyStyleClass.esriStyleClassFillSymbols);//如果是多边形
this.l_angel.Visible = false;
this.n_angle.Visible = false;
this.l_size.Visible = false;
this.n_size.Visible = false;
this.l_width.Visible = true;
this.n_width.Visible = true;
this.l_cofout.Visible = true;
this.b_cofout.Visible = true;
break;
case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolyline:
this.SetFeatureClassStyle(esriSymbologyStyleClass.esriStyleClassLineSymbols);//如果是线要素
this.l_angel.Visible = false;
this.n_angle.Visible = false;
this.l_size.Visible = false;
this.n_size.Visible = false;
this.l_width.Visible = true;
this.n_width.Visible = true;
this.l_cofout.Visible = false;
this.b_cofout.Visible = false;
break;
default:
this.Close();
break;
}
单击确定按钮:
private void b_ok_Click(object sender, EventArgs e)
{
this.pSymbol = (ISymbol)pStyleGalleryItem.Item;//取得选定的符号
this.pSymbolImage = this.pictureBox1.Image;//更新预览图像
this.Close();//关闭窗体
}
单击取消按钮:
private void b_no_Click(object sender, EventArgs e)
{
this.Close();
}
双击符号同单击确定按钮
private void axSymbologyControl1_OnDoubleClick(object sender, ISymbologyControlEvents_OnDoubleClickEvent e)
{
this.b_ok.PerformClick();
}
将选中的符号在picturebox中预览的函数为
private void axSymbologyControl1_OnStyleClassChanged(object sender, ISymbologyControlEvents_OnStyleClassChangedEvent e)
{
switch (((ISymbologyStyleClass)e.symbologyStyleClass).StyleClass)
{
case esriSymbologyStyleClass.esriStyleClassMarkerSymbols:
this.l_angel.Visible = true;
this.n_angle.Visible = true;
this.l_size.Visible = true;
this.n_size.Visible = true;
this.l_width.Visible = false;
this.n_width.Visible = false;
this.l_cofout.Visible = false;
this.b_cofout.Visible = false;
break;
case esriSymbologyStyleClass.esriStyleClassLineSymbols:
this.l_angel.Visible = false;
this.n_angle.Visible = false;
this.l_size.Visible = false;
this.n_size.Visible = false;
this.l_width.Visible = true;
this.n_width.Visible = true;
this.l_cofout.Visible = true;
this.b_cofout.Visible = false;
break;
case esriSymbologyStyleClass.esriStyleClassFillSymbols:
this.l_angel.Visible = false;
this.n_angle.Visible = false;
this.l_size.Visible = false;
this.n_size.Visible = false;
this.l_width.Visible = true;
this.n_width.Visible = true;
this.l_cofout.Visible = true;
this.b_cofout.Visible = true;
break;
default:
this.Close();
break;
}
}
选中符号触发的事件
private void axSymbologyControl1_OnItemSelected(object sender, ISymbologyControlEvents_OnItemSelectedEvent e)
{
pStyleGalleryItem = (IStyleGalleryItem)e.styleGalleryItem;
Color color;
switch (this.axSymbologyControl1.StyleClass)
{
//点符号
case esriSymbologyStyleClass.esriStyleClassMarkerSymbols:
color = this.ConvertIRgbColorToColor(((IMarkerSymbol)pStyleGalleryItem.Item).Color as IRgbColor);
//设置点符号角度和大小初始值
this.n_angle.Value = (decimal)((IMarkerSymbol)this.pStyleGalleryItem.Item).Angle;
this.n_size.Value = (decimal)((IMarkerSymbol)this.pStyleGalleryItem.Item).Size;
break;
//线符号
case esriSymbologyStyleClass.esriStyleClassLineSymbols:
color = this.ConvertIRgbColorToColor(((ILineSymbol)pStyleGalleryItem.Item).Color as IRgbColor);
//设置线宽初始值
this.n_width.Value = (decimal)((ILineSymbol)this.pStyleGalleryItem.Item).Width;
break;
//面符号
case esriSymbologyStyleClass.esriStyleClassFillSymbols:
color = this.ConvertIRgbColorToColor(((IFillSymbol)pStyleGalleryItem.Item).Color as IRgbColor);
this.b_cofout.BackColor = this.ConvertIRgbColorToColor(((IFillSymbol)pStyleGalleryItem.Item).Outline.Color as IRgbColor);
//设置外框线宽度初始值
this.n_width.Value = (decimal)((IFillSymbol)this.pStyleGalleryItem.Item).Outline.Width;
break;
default:
color = Color.Black;
break;
}
//设置按钮背景色
this.b_color.BackColor = color;
//预览符号
this.PreviewImage();
}
调整点符号的大小
private void n_size_ValueChanged(object sender, EventArgs e)
{
((IMarkerSymbol)this.pStyleGalleryItem.Item).Size = (double)this.n_size .Value;
this.PreviewImage();
}
调整点符号的角度
private void n_angle_ValueChanged(object sender, EventArgs e)
{
((IMarkerSymbol)this.pStyleGalleryItem.Item).Angle = (double)this.n_angle .Value;
this.PreviewImage();
}
调整线符号和面符号的宽度
private void n_width_ValueChanged(object sender, EventArgs e)
{
switch (this.axSymbologyControl1.StyleClass)
{
case esriSymbologyStyleClass.esriStyleClassLineSymbols:
((ILineSymbol)this.pStyleGalleryItem.Item).Width = Convert.ToDouble(this.n_width .Value);
break;
case esriSymbologyStyleClass.esriStyleClassFillSymbols:
//取得面符号的轮廓线符号
ILineSymbol pLineSymbol = ((IFillSymbol)this.pStyleGalleryItem.Item).Outline;
pLineSymbol.Width = Convert.ToDouble(this.n_width .Value);
((IFillSymbol)this.pStyleGalleryItem.Item).Outline = pLineSymbol;
break;
}
this.PreviewImage();
}
在ArcGIS Engine中,颜色由IRgbColor接口实现,而在.NET框架中,颜色则由Color结构表示。故在调整颜色参数之前,我们必须完成以上两种不同颜色表示方式的转换。
/// 《summary》
/// 将ArcGIS Engine中的IRgbColor接口转换至.NET中的Color结构
/// 《/summary》
/// 《param name=“pRgbColor”》《/param》
/// 《returns》《/returns》
public Color ConvertIRgbColorToColor(IRgbColor pRgbColor)
{
return ColorTranslator.FromOle(pRgbColor.RGB);
}
/// 《summary》
/// .NET中的Color接口转换至于ArcGIS Engine中的IColor接口的函数:
/// 《/summary》
/// 《param name=“color”》《/param》
/// 《returns》《/returns》
public IColor ConvertColorToIColor(Color color)
{
IColor pColor = new RgbColorClass();
pColor.RGB = color.B * 65536 + color.G * 256 + color.R;
return pColor;
}
选择颜色时,我们调用.NET的颜色对话框ColorDialog,选定颜色后,修改颜色按钮的背景色为选定的颜色,以方便预览。点击btnColor按钮,添加如下代码:
private void b_color_Click(object sender, EventArgs e)
{
//调用系统颜色对话框
if (this.colorDialog.ShowDialog() == DialogResult.OK)
{
//将颜色按钮的背景颜色设置为用户选定的颜色
this.b_color.BackColor = this.colorDialog.Color;
//设置符号颜色为用户选定的颜色
switch (this.axSymbologyControl1.StyleClass)
{
//点符号
case esriSymbologyStyleClass.esriStyleClassMarkerSymbols:
((IMarkerSymbol)this.pStyleGalleryItem.Item).Color = this.ConvertColorToIColor(this.colorDialog.Color);
break;
//线符号
case esriSymbologyStyleClass.esriStyleClassLineSymbols:
((ILineSymbol)this.pStyleGalleryItem.Item).Color = this.ConvertColorToIColor(this.colorDialog.Color);
break;
//面符号
case esriSymbologyStyleClass.esriStyleClassFillSymbols:
((IFillSymbol)this.pStyleGalleryItem.Item).Color = this.ConvertColorToIColor(this.colorDialog.Color);
break;
}
//更新符号预览
this.PreviewImage();
}
}
调整面符号的外框线颜色
private void b_cofout_Click(object sender, EventArgs e)
{
if (this.colorDialog.ShowDialog() == DialogResult.OK)
{
//取得面符号中的外框线符号
ILineSymbol pLineSymbol = ((IFillSymbol)this.pStyleGalleryItem.Item).Outline;
//设置外框线颜色
pLineSymbol.Color = this.ConvertColorToIColor(this.colorDialog.Color);
//重新设置面符号中的外框线符号
((IFillSymbol)this.pStyleGalleryItem.Item).Outline = pLineSymbol;
//设置按钮背景颜色
this.b_cofout .BackColor = this.colorDialog.Color;
//更新符号预览
this.PreviewImage();
}
}
添加更多符号
private void b_more_Click(object sender, EventArgs e)
{
if (this.contextMenuMoreSymbolInitiated == false)
{
string sInstall = ReadRegistry(“SOFTWARE\ESRI\Desktop10.2”);
string path = System.IO.Path.Combine(sInstall, “Styles”);
//取得菜单项数量
string[] styleNames = System.IO.Directory.GetFiles(path, “*.ServerStyle”);
ToolStripMenuItem[] symbolContextMenuItem = new ToolStripMenuItem[styleNames.Length + 1];
//循环添加其它符号菜单项到菜单
for (int i = 0; i 《 styleNames.Length; i++)
{
symbolContextMenuItem[i] = new ToolStripMenuItem();
symbolContextMenuItem[i].CheckOnClick = true;
symbolContextMenuItem[i].Text = System.IO.Path.GetFileNameWithoutExtension(styleNames[i]);
if (symbolContextMenuItem[i].Text == “ESRI”)
{
symbolContextMenuItem[i].Checked = true;
}
symbolContextMenuItem[i].Name = styleNames[i];
}
//添加“更多符号”菜单项到菜单最后一项
symbolContextMenuItem[styleNames.Length] = new ToolStripMenuItem();
symbolContextMenuItem[styleNames.Length].Text = “添加符号”;
symbolContextMenuItem[styleNames.Length].Name = “AddMoreSymbol”;
//添加所有的菜单项到菜单
this.ContextMenu.Items.AddRange(symbolContextMenuItem);
this.contextMenuMoreSymbolInitiated = true;
}
//显示菜单
this.ContextMenu.Show(this.b_more.Location);
}
当单击某一菜单项时响应ItemClicked事件,将选中的ServerStyle文件导入到SymbologyControl中并刷新。当用户单击“添加符号”菜单项时,弹出打开文件对话框,供用户选择其它的ServerStyle文件。代码如下:
private void ContextMenu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
ToolStripMenuItem pToolStripMenuItem = (ToolStripMenuItem)e.ClickedItem;
//如果单击的是“添加符号”
if (pToolStripMenuItem.Name == “AddMoreSymbol”)
{
//弹出打开文件对话框
if (this.openFileDialog1.ShowDialog() == DialogResult.OK)
{
//导入style file到SymbologyControl
this.axSymbologyControl1.LoadStyleFile(this.openFileDialog1.FileName);
//刷新axSymbologyControl控件
this.axSymbologyControl1.Refresh();
}
}
else//如果是其它选项
{
if (pToolStripMenuItem.Checked == false)
{
this.axSymbologyControl1.LoadStyleFile(pToolStripMenuItem.Name);
this.axSymbologyControl1.Refresh();
}
else
{
this.axSymbologyControl1.RemoveFile(pToolStripMenuItem.Name);
this.axSymbologyControl1.Refresh();
}
}
}
至此,自定义的符号选择器已经可以使用辣,在代码调试过程中出现过很多次bug,但是很遗憾没能及时记录下来。
TOCControl控件相当于ArcMap中左侧的目录树,需要与一个“伙伴控件”协同工作,可以是MapControl、PageLayoutControl、SceneControl或者GlobeControl。伙伴控件的设置可通过TOCControl属性对话框或用SetBuddyControl方法通过编程设置。fangfa
HitTest方法用来获取用户再TOCControl中点击的相关信息
public void HitTest(int X,int Y,ref esriTOCControlItem ItemType,ref IBasicMap BasicMap,ref ILayer,ref object Unk,ref object Data);
ItemType:TOCControl中项的类型,如none、map、layer、heading、或者legend class。
BasicMap:IMap对象。
Layer:ILayer对象。
Unk:ILegendGroup(图例组,一个图层可以有多种符号化方案)对象。
Data:用户点击的图例组中某个图例的索引号(longInt);联合使用图例组Unk和某个索引号,可以获得用户点击的图例;图例的标题头索引为-1。
图层符号选择器的实现
调用ArcMap的符号选择器
此种方法的前提是电脑上必须安装ArcGIS Desktop,该方法写在axTOCControl控件的双击事件下:
private void axTOCControl1_OnDoubleClick(object sender, ITOCControlEvents_OnDoubleClickEvent e)
{
esriTOCControlItem toccItem = esriTOCControlItem.esriTOCControlItemNone;
ILayer layer = null; IBasicMap basicMap = null; object unk = null; object data = null;//定义HitTest函数所需的参数
if(e.button==1)
{
axTOCControl1.HitTest(e.x, e.y,ref toccItem, ref basicMap, ref layer, ref unk, ref data);
{
ESRI.ArcGIS.Carto.ILegendClass pLC = new LegendClassClass();//用户点击的图例
ESRI.ArcGIS.Carto.ILegendGroup PLG = new LegendGroupClass();//用户点击的图例组
if(unk is ILegendGroup)
{
PLG = (ILegendGroup)unk;
}//获取图例组
pLC=PLG.Class[(int)data];//获取图例组中点击的具体图例
ISymbol pSym;
pSym = pLC.Symbol;
ISymbolSelector pSS = new SymbolSelectorClass();//实例化符号选择器
bool bOK = false;
pSS.AddSymbol(pSym);//添加符号的目录
bOK = pSS.SelectSymbol(0);
if(bOK)
{
pLC.Symbol = pSS.GetSymbolAt(0);//利用0索引检索选中的符号
}
this.axMapControl1.ActiveView.Refresh();
this.axTOCControl1.Refresh();
}
}
}
ISymbolSelector涉及到的方法说明:
AddSymbol:决定符号选择器出现时显示的初始符号,例如双击的是面符号,出现的界面也是面界面。
GetSymbolAt:通过0索引检索符号。
SelectSymbol:选择符号,检查用户点击确定或取消的返回值。
效果图如下:
自定义符号选择器
如果并未安装arcgis desktop又想实现该功能,可以自定义界面来实现:
界面设计如下:
窗体及控件的属性设置见下表:
[tr]控件NAMETEXT其它属性设置[/tr]FormGetSymbolByControlForm符号选择器
AxSymbologyControlaxSymbologyControl1––
groupBoxgroupBox1预览
groupBoxgroupBox2设置–
pictureBoxpictureBox1Dock设置为fill
Labell_color颜色–
Labell_size大小-
Labell_width宽度-
Labell_angel角度-
Labell_cofout外框颜色-
buttonb_color--
buttonb_cofout--
numericUpDownn_size--
numericUpDownn_width--
numericUpDownn_angle--
buttonb_more更多符号-
buttonb_color确定DialogResult属性设为OK
buttonb_color取消-
openFileDialogopenFileDialog1-Filter属性设置为:Styles 文件/*.ServerStyle
ContextMenuStripContextMenur--
ColorDialogcolorDialog--
该事件仍旧写在图例双击里:
代码的基本流程如下:
获取图层组和图层
初始化SymbologyControl的StyleClass
根据图层类型为SymbologyControl导入相应的符号样式文件
取得选定的符号
在GetSymbolByControlForm窗体中使用到的全局变量有:
private IStyleGalleryItem pStyleGalleryItem;//每一个style文件由IStyleGalleryItems组成
private ILegendClass pLegendClass;//图例组
private ILayer pLayer;//具体图层
public ISymbol pSymbol;//符号
public Image pSymbolImage;//用于预览符号
bool contextMenuMoreSymbolInitiated = false;
通过改变GetSymbolByControlForm的参数实现两个窗口之间传值,代码如下:
public GetSymbolByControlForm(ILegendClass legendClass,ILayer layer)
{
InitializeComponent();
this.pLegendClass = legendClass;//传入选择图例
this.pLayer = layer;//传入选中图层
}
初始化SymbologyControl的StyleClass,图层如果已有符号,则把符号添加到SymbologyControl中的第一个符号,并选中
private void SetFeatureClassStyle(esriSymbologyStyleClass symbologyStyleClass)
{
this.axSymbologyControl1.StyleClass = symbologyStyleClass;
ISymbologyStyleClass PsymbologyStyleClass = this.axSymbologyControl1.GetStyleClass(symbologyStyleClass);
if(this.pLegendClass!=null)
{
IStyleGalleryItem styleGalleryItem = new ServerStyleGalleryItem();
styleGalleryItem.Name = “当前符号”;
styleGalleryItem.Item = pLegendClass.Symbol;
PsymbologyStyleClass.AddItem(styleGalleryItem, 0);
this.pStyleGalleryItem = styleGalleryItem;
}/如果传入的图例不为空,则将其加入至styleGalleryItem中的第一个,默认选中
PsymbologyStyleClass.SelectItem(0);//传入图例为空,则默认选中第一个
}
载入ESRI.ServerStyle文件到SymbologyControl有两种方法:第一种方法是从注册表读取arcgis的安装路径,再使用axSymbologyControl1的LoadDesktopStyleFile()方法载入;也可以在axSymbologyControl1的属性中设置。
方法一:
读取注册表的函数(后文无用)
private string ReadRegistry(string sKey)
{
RegistryKey localMachine = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32);
string InstallDir = string.Empty;
Microsoft.Win32.RegistryKey rk = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(sKey, true);
if (rk == null)
return “”;
return (string)rk.GetValue(InstallDir);
}
2.直接设置(右键属性,Style Files,load~):
在GetSymbolByControlForm窗体的load函数中代码如下(该程序中我采用的是设置属性的方法)
private void GetSymbolByControlForm_Load(object sender, EventArgs e)
{
string sInstall = ESRI.ArcGIS.RuntimeManager.ActiveRuntime.Path;//这也是获取安装路径的一种方法
// string sInstall = ReadRegistry(“SOFTWARE\ESRI\Desktop10.2”);//获取ArcGIS安装路径
// this.axSymbologyControl1.LoadDesktopStyleFile(sInstall + “\Styles\ESRI.ServerStyle”);//载入ESRI.ServerStyle文件到SymbologyControl
IGeoFeatureLayer pGeoFeatureLayer = (IGeoFeatureLayer)pLayer;
switch(((IFeatureLayer)pLayer).FeatureClass.ShapeType)//确定图层的类型,设置空间按的StyleClass,设置各控件的可见性
{
case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint:
this.SetFeatureClassStyle(esriSymbologyStyleClass.esriStyleClassMarkerSymbols);//如果是点要素
this.l_angel.Visible = true;
this.n_angle.Visible = true;
this.l_size.Visible = true;
this.n_size.Visible = true;
this.l_width.Visible = false;
this.n_width.Visible = false;
this.l_cofout.Visible = false;
this.b_cofout.Visible = false;
break;
case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolygon:
this.SetFeatureClassStyle(esriSymbologyStyleClass.esriStyleClassFillSymbols);//如果是多边形
this.l_angel.Visible = false;
this.n_angle.Visible = false;
this.l_size.Visible = false;
this.n_size.Visible = false;
this.l_width.Visible = true;
this.n_width.Visible = true;
this.l_cofout.Visible = true;
this.b_cofout.Visible = true;
break;
case ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolyline:
this.SetFeatureClassStyle(esriSymbologyStyleClass.esriStyleClassLineSymbols);//如果是线要素
this.l_angel.Visible = false;
this.n_angle.Visible = false;
this.l_size.Visible = false;
this.n_size.Visible = false;
this.l_width.Visible = true;
this.n_width.Visible = true;
this.l_cofout.Visible = false;
this.b_cofout.Visible = false;
break;
default:
this.Close();
break;
}
单击确定按钮:
private void b_ok_Click(object sender, EventArgs e)
{
this.pSymbol = (ISymbol)pStyleGalleryItem.Item;//取得选定的符号
this.pSymbolImage = this.pictureBox1.Image;//更新预览图像
this.Close();//关闭窗体
}
单击取消按钮:
private void b_no_Click(object sender, EventArgs e)
{
this.Close();
}
双击符号同单击确定按钮
private void axSymbologyControl1_OnDoubleClick(object sender, ISymbologyControlEvents_OnDoubleClickEvent e)
{
this.b_ok.PerformClick();
}
将选中的符号在picturebox中预览的函数为
private void axSymbologyControl1_OnStyleClassChanged(object sender, ISymbologyControlEvents_OnStyleClassChangedEvent e)
{
switch (((ISymbologyStyleClass)e.symbologyStyleClass).StyleClass)
{
case esriSymbologyStyleClass.esriStyleClassMarkerSymbols:
this.l_angel.Visible = true;
this.n_angle.Visible = true;
this.l_size.Visible = true;
this.n_size.Visible = true;
this.l_width.Visible = false;
this.n_width.Visible = false;
this.l_cofout.Visible = false;
this.b_cofout.Visible = false;
break;
case esriSymbologyStyleClass.esriStyleClassLineSymbols:
this.l_angel.Visible = false;
this.n_angle.Visible = false;
this.l_size.Visible = false;
this.n_size.Visible = false;
this.l_width.Visible = true;
this.n_width.Visible = true;
this.l_cofout.Visible = true;
this.b_cofout.Visible = false;
break;
case esriSymbologyStyleClass.esriStyleClassFillSymbols:
this.l_angel.Visible = false;
this.n_angle.Visible = false;
this.l_size.Visible = false;
this.n_size.Visible = false;
this.l_width.Visible = true;
this.n_width.Visible = true;
this.l_cofout.Visible = true;
this.b_cofout.Visible = true;
break;
default:
this.Close();
break;
}
}
选中符号触发的事件
private void axSymbologyControl1_OnItemSelected(object sender, ISymbologyControlEvents_OnItemSelectedEvent e)
{
pStyleGalleryItem = (IStyleGalleryItem)e.styleGalleryItem;
Color color;
switch (this.axSymbologyControl1.StyleClass)
{
//点符号
case esriSymbologyStyleClass.esriStyleClassMarkerSymbols:
color = this.ConvertIRgbColorToColor(((IMarkerSymbol)pStyleGalleryItem.Item).Color as IRgbColor);
//设置点符号角度和大小初始值
this.n_angle.Value = (decimal)((IMarkerSymbol)this.pStyleGalleryItem.Item).Angle;
this.n_size.Value = (decimal)((IMarkerSymbol)this.pStyleGalleryItem.Item).Size;
break;
//线符号
case esriSymbologyStyleClass.esriStyleClassLineSymbols:
color = this.ConvertIRgbColorToColor(((ILineSymbol)pStyleGalleryItem.Item).Color as IRgbColor);
//设置线宽初始值
this.n_width.Value = (decimal)((ILineSymbol)this.pStyleGalleryItem.Item).Width;
break;
//面符号
case esriSymbologyStyleClass.esriStyleClassFillSymbols:
color = this.ConvertIRgbColorToColor(((IFillSymbol)pStyleGalleryItem.Item).Color as IRgbColor);
this.b_cofout.BackColor = this.ConvertIRgbColorToColor(((IFillSymbol)pStyleGalleryItem.Item).Outline.Color as IRgbColor);
//设置外框线宽度初始值
this.n_width.Value = (decimal)((IFillSymbol)this.pStyleGalleryItem.Item).Outline.Width;
break;
default:
color = Color.Black;
break;
}
//设置按钮背景色
this.b_color.BackColor = color;
//预览符号
this.PreviewImage();
}
调整点符号的大小
private void n_size_ValueChanged(object sender, EventArgs e)
{
((IMarkerSymbol)this.pStyleGalleryItem.Item).Size = (double)this.n_size .Value;
this.PreviewImage();
}
调整点符号的角度
private void n_angle_ValueChanged(object sender, EventArgs e)
{
((IMarkerSymbol)this.pStyleGalleryItem.Item).Angle = (double)this.n_angle .Value;
this.PreviewImage();
}
调整线符号和面符号的宽度
private void n_width_ValueChanged(object sender, EventArgs e)
{
switch (this.axSymbologyControl1.StyleClass)
{
case esriSymbologyStyleClass.esriStyleClassLineSymbols:
((ILineSymbol)this.pStyleGalleryItem.Item).Width = Convert.ToDouble(this.n_width .Value);
break;
case esriSymbologyStyleClass.esriStyleClassFillSymbols:
//取得面符号的轮廓线符号
ILineSymbol pLineSymbol = ((IFillSymbol)this.pStyleGalleryItem.Item).Outline;
pLineSymbol.Width = Convert.ToDouble(this.n_width .Value);
((IFillSymbol)this.pStyleGalleryItem.Item).Outline = pLineSymbol;
break;
}
this.PreviewImage();
}
在ArcGIS Engine中,颜色由IRgbColor接口实现,而在.NET框架中,颜色则由Color结构表示。故在调整颜色参数之前,我们必须完成以上两种不同颜色表示方式的转换。
/// 《summary》
/// 将ArcGIS Engine中的IRgbColor接口转换至.NET中的Color结构
/// 《/summary》
/// 《param name=“pRgbColor”》《/param》
/// 《returns》《/returns》
public Color ConvertIRgbColorToColor(IRgbColor pRgbColor)
{
return ColorTranslator.FromOle(pRgbColor.RGB);
}
/// 《summary》
/// .NET中的Color接口转换至于ArcGIS Engine中的IColor接口的函数:
/// 《/summary》
/// 《param name=“color”》《/param》
/// 《returns》《/returns》
public IColor ConvertColorToIColor(Color color)
{
IColor pColor = new RgbColorClass();
pColor.RGB = color.B * 65536 + color.G * 256 + color.R;
return pColor;
}
选择颜色时,我们调用.NET的颜色对话框ColorDialog,选定颜色后,修改颜色按钮的背景色为选定的颜色,以方便预览。点击btnColor按钮,添加如下代码:
private void b_color_Click(object sender, EventArgs e)
{
//调用系统颜色对话框
if (this.colorDialog.ShowDialog() == DialogResult.OK)
{
//将颜色按钮的背景颜色设置为用户选定的颜色
this.b_color.BackColor = this.colorDialog.Color;
//设置符号颜色为用户选定的颜色
switch (this.axSymbologyControl1.StyleClass)
{
//点符号
case esriSymbologyStyleClass.esriStyleClassMarkerSymbols:
((IMarkerSymbol)this.pStyleGalleryItem.Item).Color = this.ConvertColorToIColor(this.colorDialog.Color);
break;
//线符号
case esriSymbologyStyleClass.esriStyleClassLineSymbols:
((ILineSymbol)this.pStyleGalleryItem.Item).Color = this.ConvertColorToIColor(this.colorDialog.Color);
break;
//面符号
case esriSymbologyStyleClass.esriStyleClassFillSymbols:
((IFillSymbol)this.pStyleGalleryItem.Item).Color = this.ConvertColorToIColor(this.colorDialog.Color);
break;
}
//更新符号预览
this.PreviewImage();
}
}
调整面符号的外框线颜色
private void b_cofout_Click(object sender, EventArgs e)
{
if (this.colorDialog.ShowDialog() == DialogResult.OK)
{
//取得面符号中的外框线符号
ILineSymbol pLineSymbol = ((IFillSymbol)this.pStyleGalleryItem.Item).Outline;
//设置外框线颜色
pLineSymbol.Color = this.ConvertColorToIColor(this.colorDialog.Color);
//重新设置面符号中的外框线符号
((IFillSymbol)this.pStyleGalleryItem.Item).Outline = pLineSymbol;
//设置按钮背景颜色
this.b_cofout .BackColor = this.colorDialog.Color;
//更新符号预览
this.PreviewImage();
}
}
添加更多符号
private void b_more_Click(object sender, EventArgs e)
{
if (this.contextMenuMoreSymbolInitiated == false)
{
string sInstall = ReadRegistry(“SOFTWARE\ESRI\Desktop10.2”);
string path = System.IO.Path.Combine(sInstall, “Styles”);
//取得菜单项数量
string[] styleNames = System.IO.Directory.GetFiles(path, “*.ServerStyle”);
ToolStripMenuItem[] symbolContextMenuItem = new ToolStripMenuItem[styleNames.Length + 1];
//循环添加其它符号菜单项到菜单
for (int i = 0; i 《 styleNames.Length; i++)
{
symbolContextMenuItem[i] = new ToolStripMenuItem();
symbolContextMenuItem[i].CheckOnClick = true;
symbolContextMenuItem[i].Text = System.IO.Path.GetFileNameWithoutExtension(styleNames[i]);
if (symbolContextMenuItem[i].Text == “ESRI”)
{
symbolContextMenuItem[i].Checked = true;
}
symbolContextMenuItem[i].Name = styleNames[i];
}
//添加“更多符号”菜单项到菜单最后一项
symbolContextMenuItem[styleNames.Length] = new ToolStripMenuItem();
symbolContextMenuItem[styleNames.Length].Text = “添加符号”;
symbolContextMenuItem[styleNames.Length].Name = “AddMoreSymbol”;
//添加所有的菜单项到菜单
this.ContextMenu.Items.AddRange(symbolContextMenuItem);
this.contextMenuMoreSymbolInitiated = true;
}
//显示菜单
this.ContextMenu.Show(this.b_more.Location);
}
当单击某一菜单项时响应ItemClicked事件,将选中的ServerStyle文件导入到SymbologyControl中并刷新。当用户单击“添加符号”菜单项时,弹出打开文件对话框,供用户选择其它的ServerStyle文件。代码如下:
private void ContextMenu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
ToolStripMenuItem pToolStripMenuItem = (ToolStripMenuItem)e.ClickedItem;
//如果单击的是“添加符号”
if (pToolStripMenuItem.Name == “AddMoreSymbol”)
{
//弹出打开文件对话框
if (this.openFileDialog1.ShowDialog() == DialogResult.OK)
{
//导入style file到SymbologyControl
this.axSymbologyControl1.LoadStyleFile(this.openFileDialog1.FileName);
//刷新axSymbologyControl控件
this.axSymbologyControl1.Refresh();
}
}
else//如果是其它选项
{
if (pToolStripMenuItem.Checked == false)
{
this.axSymbologyControl1.LoadStyleFile(pToolStripMenuItem.Name);
this.axSymbologyControl1.Refresh();
}
else
{
this.axSymbologyControl1.RemoveFile(pToolStripMenuItem.Name);
this.axSymbologyControl1.Refresh();
}
}
}
至此,自定义的符号选择器已经可以使用辣,在代码调试过程中出现过很多次bug,但是很遗憾没能及时记录下来。
举报