在Arcmap中使用Sapefile格式的矢量数据时,经常会用到其属性查询的功能,弹出窗体然后用户鼠标点击或手动输入查询条件,进而查询到感兴趣的要素。在AE二次开发中也经常需要这个功能,于是在此记录整个开发过程。
首先当然是需要构建一个Visual C# Windows窗体应用程序,然后添加axMapControl等控件,这些过程不再赘述。
然后新建一个名为FormQueryAttr.cs的窗体,用于属性查询时弹出,其界面设置为如下:
其中要素为:一个ComboBox(cboLayer);两个ListBox(listBoxField和listBoxValue);一个GroupBox;一个TextBox(textBoxSql)
21个Button,表达式所需的19个button的名称如下:
btnequal、btnunequal、btnis、btnlike、btnmore、btnless、btnmoe、btnloe、btnor、btnnull、btnnot、btnand、btnin、btnunderline、btnpercent、btncharacter、btnbetween、btnspace、btnempty
点击查看代码,添加以下变量并在构造函数中添加以下语句:
1 //地图数据 2 private AxMapControl mMapControl; 3 //选中的图层 4 private IFeatureLayer mFeatureLayer; 5 //根据所选择的图层查询得到的特征类 6 private IFeatureClass pFeatureClass = null; 7 8 public FormQueryAttr(AxMapControl mapControl) 9 { 10 InitializeComponent(); 11 this.mMapControl = mapControl; 12 }
接着回到程序主界面,添加属性查询的Button按钮,在其点击响应函数中添加如下代码:
1 //属性查询 2 private void barButtonItem13_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) 3 { 4 FormQueryAttr formqueryattr = new FormQueryAttr(this.axMapControl1); 5 formqueryattr.Show(); 6 }
至此,程序运行且用户点击“属性查询”按钮时,会初始化FormQueryAttr.cs窗体,将整个axMapControl作为参数传入,并显示窗体。
然后再回到FormQueryAttr.cs窗体的代码中,做以下更改:
在其Load函数中为cboLayer添加所有图层名称,代码如下:
1 private void FormQueryAttr_Load(object sender, EventArgs e) 2 { 3 //MapControl中没有图层时返回 4 if (this.mMapControl.LayerCount <= 0) 5 return; 6 //获取MapControl中的全部图层名称,并加入ComboBox 7 ILayer pLayer; 8 //图层名称 9 string strLayerName; 10 for (int i = 0; i < this.mMapControl.LayerCount; i++) 11 { 12 pLayer = this.mMapControl.get_Layer(i); 13 strLayerName = pLayer.Name; 14 //图层名称加入cboLayer 15 this.cboLayer.Items.Add(strLayerName); 16 } 17 //默认显示第一个选项 18 this.cboLayer.SelectedIndex = 0; 19 }
为cboLayer添加SelectedIndexChanged响应事件,其中代码如下:
1 private void cboLayer_SelectedIndexChanged(object sender, EventArgs e) 2 { 3 this.listBoxField.Items.Clear(); 4 //获取cboLayer中选中的图层 5 mFeatureLayer = mMapControl.get_Layer(cboLayer.SelectedIndex) as IFeatureLayer; 6 pFeatureClass = mFeatureLayer.FeatureClass; 7 string strFldName; 8 for (int i = 0; i < pFeatureClass.Fields.FieldCount; i++) 9 { 10 strFldName = pFeatureClass.Fields.get_Field(i).Name; 11 this.listBoxField.Items.Add(strFldName); 12 } 13 this.listBoxField.SelectedIndex = 0; 14 this.label8.Text = mFeatureLayer.Name; 15 }
为listBoxField添加SelectedIndexChanged和DoubleClick响应事件,其中代码如下:
1 private void listBoxField_SelectedIndexChanged(object sender, EventArgs e) 2 { 3 string sFieldName = listBoxField.Text; 4 listBoxValue.Items.Clear(); 5 int iFieldIndex = 0; 6 IField pField = null; 7 IFeatureCursor pFeatCursor = pFeatureClass.Search(null, true); 8 IFeature pFeat = pFeatCursor.NextFeature(); 9 iFieldIndex = pFeatureClass.FindField(sFieldName); 10 pField = pFeatureClass.Fields.get_Field(iFieldIndex); 11 while (pFeat != null) 12 { 13 listBoxValue.Items.Add(pFeat.get_Value(iFieldIndex)); 14 pFeat = pFeatCursor.NextFeature(); 15 } 16 17 } 18 private void listBoxField_DoubleClick(object sender, EventArgs e) 19 { 20 textBoxSql.SelectedText = listBoxField.SelectedItem.ToString() + " "; 21 }
为listBoxValue添加DoubleClick响应事件,其中代码如下:
1 private void listBoxValue_DoubleClick(object sender, EventArgs e) 2 { 3 textBoxSql.SelectedText = listBoxValue.SelectedItem.ToString() + " "; 4 }
然后对“表达式”中的按钮添加对应的点击响应函数,具体代码如下:
1 private void btnequal_Click(object sender, EventArgs e) 2 { 3 textBoxSql.SelectedText = "= "; 4 } 5 6 private void btnis_Click(object sender, EventArgs e) 7 { 8 textBoxSql.SelectedText = "is "; 9 } 10 11 private void btncharacter_Click(object sender, EventArgs e) 12 { 13 textBoxSql.SelectedText = "'' "; 14 } 15 16 private void btnempty_Click(object sender, EventArgs e) 17 { 18 this.textBoxSql.Text = ""; 19 } 20 21 private void btnunequal_Click(object sender, EventArgs e) 22 { 23 textBoxSql.SelectedText = "!= "; 24 } 25 26 private void btnlike_Click(object sender, EventArgs e) 27 { 28 textBoxSql.SelectedText = "like "; 29 } 30 31 private void btnmore_Click(object sender, EventArgs e) 32 { 33 textBoxSql.SelectedText = "> "; 34 } 35 36 private void btnmoe_Click(object sender, EventArgs e) 37 { 38 textBoxSql.SelectedText = ">= "; 39 } 40 41 private void btnloe_Click(object sender, EventArgs e) 42 { 43 textBoxSql.SelectedText = "<= "; 44 } 45 46 private void btnor_Click(object sender, EventArgs e) 47 { 48 textBoxSql.SelectedText = " or "; 49 } 50 51 private void btnnull_Click(object sender, EventArgs e) 52 { 53 textBoxSql.SelectedText = "Null "; 54 } 55 56 private void btnless_Click(object sender, EventArgs e) 57 { 58 textBoxSql.SelectedText = "< "; 59 } 60 61 private void btnnot_Click(object sender, EventArgs e) 62 { 63 textBoxSql.SelectedText = " Not "; 64 } 65 66 private void btnand_Click(object sender, EventArgs e) 67 { 68 textBoxSql.SelectedText = " And "; 69 } 70 71 private void btnin_Click(object sender, EventArgs e) 72 { 73 textBoxSql.SelectedText = " In "; 74 } 75 76 private void btnunderline_Click(object sender, EventArgs e) 77 { 78 textBoxSql.SelectedText = "_"; 79 } 80 81 private void btnpercent_Click(object sender, EventArgs e) 82 { 83 textBoxSql.SelectedText = "% "; 84 } 85 86 private void btnbetween_Click(object sender, EventArgs e) 87 { 88 textBoxSql.SelectedText = " Between "; 89 } 90 91 private void btnspace_Click(object sender, EventArgs e) 92 { 93 textBoxSql.SelectedText = " "; 94 }
最后对按钮“查找”和“取消”添加点击响应函数,代码如下:
1 private void button1_Click(object sender, EventArgs e) 2 { 3 try 4 { 5 mMapControl.Map.ClearSelection(); //清除上次查询结果 6 IActiveView pActiveView = mMapControl.Map as IActiveView; 7 //pQueryFilter的实例化 8 IQueryFilter pQueryFilter = new QueryFilterClass(); 9 //设置查询过滤条件 10 pQueryFilter.WhereClause = textBoxSql.Text; 11 //search的参数第一个为过滤条件,第二个为是否重复执行 12 IFeatureCursor pFeatureCursor = mFeatureLayer.Search(pQueryFilter, false); 13 //获取查询到的要素 14 IFeature pFeature = pFeatureCursor.NextFeature(); 15 //判断是否获取到要素 16 while (pFeature != null) 17 { 18 mMapControl.Map.SelectFeature(mFeatureLayer, pFeature); //选择要素 19 pFeature = pFeatureCursor.NextFeature(); 20 } 21 pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, null); 22 pActiveView.Refresh();//刷新图层 23 } 24 catch (Exception ex) 25 { 26 MessageBox.Show(ex.Message); 27 } 28 29 } 30 31 private void button2_Click(object sender, EventArgs e) 32 { 33 this.Hide(); 34 }
到此为止,所有属性查询的工作已经完成,使用效果如下图所示:
如果需要清除所选要素,则添加按钮,并在其点击响应函数中添加如下代码即可:
1 //清空查询 2 private void barButtonItem14_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) 3 { 4 axMapControl1.Map.ClearSelection(); 5 axMapControl1.Refresh(); 6 }