在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 }