[GIS] Add Attritube Field to Combo Box on Form

arcgis-10.0arcobjectstoolbarvb.netvisual studio

I am trying to create a user box that:

  1. When the button on the toolbar is clicked, a user form appears with a combo box filled in with a feature's location (Taken from the attribute table – such as I-10 and I-15)
  2. Once the user selects a location from the combo box, additional text boxes on the form are populated with additional attribute information of that selected feature (i.e., description, costs, etc).
  3. The user can change the additional attribute information and then click update to save the changes.

I have this running in ArcGIS 9.3 using VBA ArcObjects and am now trying to convert it to VB.Net using Visual Basic 2008 Express.

I am having issues with my AddItem Sub Routine- it says that my List Count, List, and AddItem are not members of the System.Windows.Form.ComboBox. Suggestions on what to change?

Errors:

Public Sub AddItem(ByVal sItem As String, ByVal cmbBox As System.Windows.Forms.ComboBox)
    ' adds item retaining alphabetic order, unique values
    Dim l As Long
    For l = 0 To cmbBox.ListCount - 1
        Select Case StrComp(cmbBox.List(l), sItem, vbTextCompare)
            Case 0 : Exit Sub ' already in the combobox
            Case 1
                cmbBox.AddItem(sItem, l)
                Exit Sub
        End Select
    Next l
    cmbBox.AddItem(sItem)

    End Sub

Entire Code:

Public Class TransportationImprovementLinesAttributesForm

    Public pMxDoc As IMxDocument

    Private Sub cmdCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdCancel.Click
        Dim pMxDoc As IMxDocument
        pMxDoc = My.ArcMap.Document
        Dim pMap As IMap
        pMap = pMxDoc.FocusMap

        'Close Form when button is pushed
        Me.Close()

        'Clear Selection and Refresh View
        pMap.ClearSelection()
        pMxDoc.ActiveView.Refresh()

    End Sub

    Private Sub TransportationImprovementLinesAttributesForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'Get Improvement Projects FeatureLayer
        Dim pFeatLyr As IFeatureLayer
        pFeatLyr = GetLayerByTOC("RV_ImprovementLines")

        'Sort Location combobox
        Call SortCboFromFeatLyr(pFeatLyr, "LOCATION", cboLocation)
    End Sub
    Private Sub cmdUpdate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdUpdate.Click
        Try
            Dim pMxDoc As IMxDocument
            pMxDoc = My.ArcMap.Document
            Dim pMap As IMap
            pMap = pMxDoc.FocusMap

            'Get a reference to the editor.
            Dim editor As IEditor
            editor = My.ArcMap.Application.FindExtensionByName("esriEditor.Editor")

            'Get Crossings FeatureLayer
            Dim pFeatLyr As IFeatureLayer
            pFeatLyr = GetLayerByTOC("RV_ImprovementLines")

            'Get Dataset from FeatureLayer
            Dim pEditDataset As IDataset
            pEditDataset = pFeatLyr

            'If not editing, start editing dataset's Workspace
            If editor.EditState <> esriEditState.esriStateEditing Then
                editor.StartEditing(pEditDataset.Workspace)
                'editor.StartOperation()
            End If


            'Get Feature Reference
            Dim pQueryFilter As IQueryFilter
            pQueryFilter = New QueryFilter

            ' Set the where clause
            pQueryFilter.WhereClause = "LOCATION ='" & cboLocation.Text & "'"

            ' Execute the query filter
            Dim pFeatureCursor As IFeatureCursor
            pFeatureCursor = pFeatLyr.Search(pQueryFilter, False)

            'Initialize first (only) feature
            Dim pFeat As IFeature
            pFeat = pFeatureCursor.NextFeature

            'Update attributes with user input
            pFeat.Value(pFeat.Fields.FindField("Location")) = cboLocation.Text
            pFeat.Value(pFeat.Fields.FindField("ID")) = txtProjectID.Text
            pFeat.Value(pFeat.Fields.FindField("Phase")) = txtPhase.Text
            pFeat.Value(pFeat.Fields.FindField("Descriptio")) = txtDescription.Text
            pFeat.Value(pFeat.Fields.FindField("Agency")) = txtAgency.Text
            pFeat.Value(pFeat.Fields.FindField("Cost")) = txtCost.Text
            pFeat.Value(pFeat.Fields.FindField("DateEdited")) = txtDate.Text
            pFeat.Value(pFeat.Fields.FindField("UserEdited")) = txtEdit.Text
            'pFeatureCursor.UpdateFeature(pFeat)
            ' pFeat = pFeatureCursor.NextFeature

            'Stop editing and save edits
            editor.StopEditing(True)

            ' Flag the new selection
            My.ArcMap.Document.ActivatedView.PartialRefresh(ESRI.ArcGIS.Carto.esriViewDrawPhase.esriViewGeoSelection, Nothing, Nothing)

            'Close form
            Me.Close()

        Catch ex As Exception
            Windows.Forms.MessageBox.Show(ex.ToString, "error")


        End Try
    End Sub

    Public Sub SortCboFromFeatLyr(ByVal pFeatLyr As IFeatureLayer, ByVal strField As String, ByVal CmboBox As System.Windows.Forms.ComboBox)

        'Pass FeatureLayer to Table
        Dim pTable As ITable
        pTable = pFeatLyr

        'Create TableSort object
        Dim pTS As ITableSort
        pTS = New TableSort

        'Specify TableSort properties
        With pTS
            .Fields = strField  'Field to sort (just one for now)
            .Ascending(strField) = True  'Ascending or Descending
            .CaseSensitive(strField) = False
            .Table = pTable  'Pass Table in
            .Sort(Nothing)  'Perform the sort
        End With

        'Get index of Field's position in FeatureLayer table
        Dim lngFldIdx As Long
        lngFldIdx = pFeatLyr.FeatureClass.Fields.FindFieldByAliasName(strField)

        'Pass sorted Rows to Cursor
        Dim pCursor As ICursor
        pCursor = pTS.Rows

        'Get first Row in Cursor
        Dim pRow As IRow
        pRow = pCursor.NextRow

        'Loop through Cursor to add items
        Do While Not pRow Is Nothing
            AddItem(CStr(pRow.Value(lngFldIdx)), CmboBox)
            pRow = pCursor.NextRow
        Loop

    End Sub

    Public Sub AddItem(ByVal sItem As String, ByVal cmbBox As System.Windows.Forms.ComboBox)

        ' adds item retaining alphabetic order, unique values
        Dim l As Long
        For l = 0 To cmbBox.ListCount - 1
            Select Case StrComp(cmbBox.List(l), sItem, vbTextCompare)
                Case 0 : Exit Sub ' already in the combobox
                Case 1
                    cmbBox.AddItem(sItem, l)
                    Exit Sub
            End Select
        Next l
        cmbBox.AddItem(sItem)

    End Sub
    Private Sub cboLocation_Change()
        GetAttributesQuery()
        SelectMapFeatures()
    End Sub

    Sub GetAttributesQuery()
        Dim pMap As IMap
        Dim pDoc As IMxDocument
        pDoc = My.ArcMap.Document
        pMap = pDoc.FocusMap
        Dim pLayer As IFeatureLayer
        pLayer = GetLayerByTOC("RV_ImprovementLines")
        Dim pFL As IFeatureClass
        pFL = pLayer.FeatureClass
        Dim pTable As ITable
        pTable = pLayer.FeatureClass
        Dim pQueryFilter As IQueryFilter
        Dim pCursor As ICursor
        ' create a query filter
        pQueryFilter = New QueryFilter

        ' create the where statement
        pQueryFilter.WhereClause = "LOCATION = '" & cboLocation.Text(cboLocation.Text) & "'"

        ' query the table passed into the function and use a cursor to hold the results
        pCursor = pTable.Search(pQueryFilter, False)
        Dim pRow As IRow
        pRow = pCursor.NextRow
        txtProjectID.Text = pRow.Value(pRow.Fields.FindField("ID"))
        txtPhase.Text = pRow.Value(pRow.Fields.FindField("Phase"))
        txtDescription.Text = pRow.Value(pRow.Fields.FindField("Descriptio"))
        txtAgency.Text = pRow.Value(pRow.Fields.FindField("Agency"))
        txtCost.Text = pRow.Value(pRow.Fields.FindField("Cost"))
        txtDate.Text = pRow.Value(pRow.Fields.FindField("DateEdited"))
        txtEdit.Text = pRow.Value(pRow.Fields.FindField("UserEdited"))

    End Sub

    Public Sub SelectMapFeatures()
        Dim pMxDoc As IMxDocument
        Dim pMap As IMap
        Dim pActiveView As IActiveView
        Dim pFeatureLayer As IFeatureLayer
        Dim pFeatureSelection As IFeatureSelection
        Dim pQueryFilter As IQueryFilter

        pMxDoc = My.ArcMap.Document
        pMap = pMxDoc.FocusMap
        pActiveView = pMap

        'For simplicity sake let's use the first layer in the map
        pFeatureLayer = GetLayerByTOC("TransportationImprovementProjects_Lines")
        pFeatureSelection = pFeatureLayer 'QI

        'Create the query filter
        pQueryFilter = New QueryFilter
        pQueryFilter.WhereClause = "LOCATION = '" & cboLocation.Text(cboLocation.Text) & "'"

        'Invalidate only the selection cache
        'Flag the original selection
        pActiveView.PartialRefresh(ESRI.ArcGIS.Carto.esriViewDrawPhase.esriViewGeoSelection, Nothing, Nothing)
        'Perform the selection
        pFeatureSelection.SelectFeatures(pQueryFilter, ESRI.ArcGIS.Carto.esriSelectionResultEnum.esriSelectionResultNew, False)
        'Flag the new selection
        pActiveView.PartialRefresh(ESRI.ArcGIS.Carto.esriViewDrawPhase.esriViewGeoSelection, Nothing, Nothing)

    End Sub
    Public Function GetSelection(ByVal pFeatLyr As IFeatureLayer) As ISelectionSet

        'Gets selection of feature layer and returns selection set
        'Initialize the required variables
        pMxDoc = My.ArcMap.Application.Document
        Dim pFeatSel As IFeatureSelection
        pFeatSel = pFeatLyr

        GetSelection = pFeatSel.SelectionSet

    End Function

    Public Function GetLayerByTOC(ByVal lyrName As String) As IFeatureLayer

        'This function finds a feature layer based on its TOC Name
        'Initalize global variables
        pMxDoc = My.ArcMap.Application.Document
        Dim pMap As IMap
        pMap = pMxDoc.FocusMap

        Dim lyrCntr As Integer
        Dim pFeatLyr As IFeatureLayer

        For lyrCntr = 0 To pMap.LayerCount - 1

            'Ensure that the layer is valid
            If pMap.Layer(lyrCntr).Valid = True Then

                'Ensure that the layer is a feature layer
                If TypeOf pMap.Layer(lyrCntr) Is IFeatureLayer Then
                    pFeatLyr = pMap.Layer(lyrCntr)

                    If UCase(pMap.Layer(lyrCntr).Name) = UCase(lyrName) Then
                        GetLayerByTOC = pFeatLyr
                        Exit Function
                    End If
                End If
            End If
        Next lyrCntr

        Return Nothing
        'Layer not found. Show a message
        MsgBox("Layer " & lyrName & " not found !", vbCritical, "Error")

    End Function

    Public Function GetFeatSelCount(ByVal pFeatLyr As IFeatureLayer) As Long

        'Returns # of selected featurues of feature layer as long integer

        Dim pFeatSel As IFeatureSelection
        pFeatSel = pFeatLyr

        Dim pFeatSelectionSet As ISelectionSet
        pFeatSelectionSet = pFeatSel.SelectionSet

        GetFeatSelCount = pFeatSelectionSet.Count
    End Function

End Class

Best Answer

The syntax for combobox (as well as other controls) is different in VB.NET. You should review the help to see the changes.

cmbBox.ListCount --> cmbBox.Items.Count
cmbBox.List(l) --> cmbBox.Items.Item(l)
cmbBox.AddItem(sItem, l) --> cmbBox.Items.Insert(l, sItem)
cmbBox.AddItem(sItem) --> cmbBox.Items.Add(sItem)
Related Question