Fields will not load in my combobox

1318
4
08-26-2016 01:13 PM
New Contributor II

I have a combo box that has the layers from the TOC loaded into them.  Now I want to be able to select the layer (usually shapefiles) and load the fields but im a newbie when it comes to ArcObjects.

This is what I have which i know is wrong:

private void cboLocation_SelectedIndexChanged(object sender, EventArgs e)

        {

           

            cboRegion.Items.Clear();

            cboLevel.Items.Clear();

            PointLayers selectedPntLayer = cboLocation.SelectedItem as PointLayers;

            IFeatureLayer selectedFL = selectedPntLayer.pointLayer as IFeatureLayer;

            IFeatureClass getInputFC = selectedFL.FeatureClass ;

 

            for (int i = 0; i < getInputFC.Fields.FieldCount; i++)

            {

                cboRegion.Items.Add(getInputFC.Fields.get_Field(i).Name);
                cboLevel.Items.Add(getInputFC.Fields.get_Field(i).Name);

            }

        }

I get an error at the IFeatureLayer line saying:

"Object reference not set to an instance of an object."

Im sure it is easy to fix but im a newbie, anyone out there know how to fix this?

Reply
0 Kudos
4 Replies
by Esri Contributor
Esri Contributor

Welcome to ArcObjects. There are lots of resources for learning ArcObjects:

Samples on Github (ArcObjects .NET)

https://github.com/Esri/developer-support/tree/gh-pages/arcobjects-net

One of the samples on the Github page above should provide an answer to your question.

Help for ArcObjects can be found in the Online Help for ArcObjects located here:

ArcObjects Online Help

http://resources.arcgis.com/en/help/arcobjects-net/conceptualhelp/#/Learning_ArcObjects/0001000000p1...

More specifically, you will need to go through the documentation under the topic below in order to understand how to navigate the map, and its layers:

Interacting with and configuring maps, layers, and graphics

http://resources.arcgis.com/en/help/arcobjects-net/conceptualhelp/#/Interacting_with_and_configuring...

Reply
0 Kudos
New Contributor II

Hello thanks for the response.   I could not find what I was looking for on those sites.

Reply
0 Kudos
MVP Honored Contributor

Here's one example of an add-in where I fill a combobox with the fields of a layer selected from another combobox. When I initialize the form in the function CreateLayerList, I fill the layer combobox with specific layer types (point, line, or polygon) while excluding other layer types (rasters, group layers, etc). The SelectedIndexChanged function then fills the combobox with fields from the selected layer.

Private pEnumLayers As ESRI.ArcGIS.Carto.IEnumLayer
Private pSampleLayer As ESRI.ArcGIS.Carto.ILayer2

    Private Sub CreateLayerList()

        Dim pFLayer As ESRI.ArcGIS.Carto.IFeatureLayer2
        Dim pLayer As ESRI.ArcGIS.Carto.ILayer

        cboLayer.Items.Clear()

        Try
            If My.ArcMap.Document.FocusMap.LayerCount > 0 Then
                pEnumLayers = My.ArcMap.Document.FocusMap.Layers
                pLayer = pEnumLayers.Next

                Do Until pLayer Is Nothing
                    If pLayer.Valid Then
                        If TypeOf pLayer Is ESRI.ArcGIS.Carto.IFeatureLayer2 Then
                            pFLayer = pLayer
                            If pFLayer.ShapeType = ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolygon Or pFLayer.ShapeType = ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint Or pFLayer.ShapeType = ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolyline Then cboFrame.Items.Add(pLayer.Name)
                        End If
                    End If
                    pLayer = pEnumLayers.Next
                Loop
            End If

        Catch ex As Exception
            System.Windows.Forms.MessageBox.Show("Error initializing list")
        End Try
    End Sub

    Private Sub cboLayer_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboLayer.SelectedIndexChanged

        Dim pFields As ESRI.ArcGIS.Geodatabase.IFields
        Dim pFLayer As ESRI.ArcGIS.Carto.IFeatureLayer2

        cboMetricField.Items.Clear()
        cboMetricField.Text = ""

        If pEnumLayers Is Nothing Then Exit Sub
        pEnumLayers.Reset()
        pSampleLayer = pEnumLayers.Next
        Do Until pSampleLayer Is Nothing
            If pSampleLayer.Name = cboLayer.Text And Not TypeOf pSampleLayer Is ESRI.ArcGIS.Carto.IGroupLayer Then Exit Do
            pSampleLayer = pEnumLayers.Next
        Loop

        If pSampleLayer Is Nothing Then
            System.Windows.Forms.MessageBox.Show("Cannot find the layer '" & cboLayer.Text & "'...exiting routine.", "", Windows.Forms.MessageBoxButtons.OK, Windows.Forms.MessageBoxIcon.Exclamation)
            Exit Sub
        End If

        pFLayer = pSampleLayer

        pFields = pFLayer.FeatureClass.Fields
        For i As Integer = 0 To pFields.FieldCount - 1
            If pFields.Field(i).Type < 4 Then cboMetricField.Items.Add(pFields.Field(i).Name)
        Next

    End Sub
Reply
0 Kudos
Regular Contributor II

Here is an example addin I just wrote up for this scenario. After I've had a chance to clean up the code I'll upload it to my GitHub account and send you the url. I designed my code so that it would add/remove the names of the feature layers to the first combo-box as you add, remove, or reorder layers in the TOC. When you select a name from the first combo-box it populates the names of the fields into the second combo-box.

Code for first combo-box

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Linq;

namespace ArcMapAddinCBX
{
    public class LayerCombo : ESRI.ArcGIS.Desktop.AddIns.ComboBox
    {
        public LayerCombo()
        {
            var events = ArcMap.Document.FocusMap as ESRI.ArcGIS.Carto.IActiveViewEvents_Event;

            events.ItemAdded += (item) =>
            {
                System.Diagnostics.Debug.WriteLine("Item Added");
               
                if (!(item is ESRI.ArcGIS.Carto.IFeatureLayer))
                    return;
               
                this.Add((item as ESRI.ArcGIS.Carto.ILayer).Name);
            };

            events.ItemDeleted += (item) =>
            {
                System.Diagnostics.Debug.WriteLine("Item Deleted");

                if (!(item is ESRI.ArcGIS.Carto.IFeatureLayer))
                    return;

                var items = new Dictionary<string, Stack<int>>();

                foreach (var i in this.items)
                {
                    var key = i.Caption;

                    if (items.ContainsKey(key))
                        items[key].Push(i.Cookie);
                    else
                    {
                        var stack = new Stack<int>();
                        stack.Push(i.Cookie);
                        items[key] = stack;
                    }
                }

                var name = (item as ESRI.ArcGIS.Carto.ILayer).Name;
                if (!items.ContainsKey(name))
                    return;

                var cookies = items[name];
                foreach (var cookie in cookies)
                    this.Remove(cookie);
               
            };

            events.ItemReordered += (item, toIndex) =>
            {
                System.Diagnostics.Debug.WriteLine("Item Reordered");

                this.Clear();
                // "{40A9E885-5533-11D0-98BE-00805F7CED21}" = IFeatureLayer
                var names = LoopThroughLayersOfSpecificUID(ArcMap.Document.FocusMap, "{40A9E885-5533-11D0-98BE-00805F7CED21}");
                foreach (var name in names)
                    this.Add(name);
            };
        }

        protected override void OnUpdate()
        {
            Enabled = ArcMap.Application != null;
        }

        protected override void OnSelChange(int cookie)
        {
            if (cookie < 0)
                return;

            var name = this.items.Where(s => s.Cookie == cookie).FirstOrDefault().Caption;
            var layer = LoopThroughLayersOfSpecificUID(ArcMap.Document.FocusMap, "{40A9E885-5533-11D0-98BE-00805F7CED21}", name) as ESRI.ArcGIS.Carto.IFeatureLayer;

            var fields = new List<string>();
           
            for (int i = 0; i < layer.FeatureClass.Fields.FieldCount; i++)
                fields.Add(layer.FeatureClass.Fields.Field[i].Name);

            var cbx = ESRI.ArcGIS.Desktop.AddIns.AddIn.FromID<FieldsCombo>(ThisAddIn.IDs.FieldsCombo.ToUID().Value.ToString());
            cbx.UpdateItems(fields.ToArray());           

            base.OnSelChange(cookie);
        }

        // Loop Through Layers of Specific UID Snippet (ArcObjects .NET 10.4 SDK)
        // http://desktop.arcgis.com/en/arcobjects/latest/net/webframe.htm#68527c4d-e69d-42f2-9f9e-81652dd4c329...
        public string[] LoopThroughLayersOfSpecificUID(ESRI.ArcGIS.Carto.IMap map, System.String layerCLSID)
        {
            if (map == null || layerCLSID == null)
                return null;

            List<string> names = new List<string>();

            ESRI.ArcGIS.esriSystem.IUID uid = new ESRI.ArcGIS.esriSystem.UIDClass { Value = layerCLSID };
            try
            {
                ESRI.ArcGIS.Carto.IEnumLayer enumLayer = map.get_Layers(((ESRI.ArcGIS.esriSystem.UID)(uid)), true); // Explicit Cast
                enumLayer.Reset();
                ESRI.ArcGIS.Carto.ILayer layer;
                while ((layer = enumLayer.Next()) != null)
                    names.Add(layer.Name);
            }
            catch (System.Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
            }

            return names.ToArray();
        }

        public ESRI.ArcGIS.Carto.ILayer LoopThroughLayersOfSpecificUID(ESRI.ArcGIS.Carto.IMap map, System.String layerCLSID, System.String layerName)
        {
            if (map == null || layerCLSID == null || layerName == null)
                return null;

            ESRI.ArcGIS.esriSystem.IUID uid = new ESRI.ArcGIS.esriSystem.UIDClass { Value = layerCLSID };
            try
            {
                ESRI.ArcGIS.Carto.IEnumLayer enumLayer = map.get_Layers(((ESRI.ArcGIS.esriSystem.UID)(uid)), true); // Explicit Cast
                enumLayer.Reset();
                ESRI.ArcGIS.Carto.ILayer layer;
                while ((layer = enumLayer.Next()) != null)
                {
                    if (layer.Name == layerName)
                        return layer;
                }
               
            }
            catch (System.Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
            }

            return null;
        }

        // Find Command and Execute Snippet (ArcObjects .NET 10.4 SDK)
        // http://desktop.arcgis.com/en/arcobjects/latest/net/webframe.htm#c3a1599b-b5ce-4822-9b65-2dc7c9f527e8...
        public ESRI.ArcGIS.Desktop.AddIns.ComboBox FindCommand(ESRI.ArcGIS.Framework.IApplication application, ESRI.ArcGIS.esriSystem.UID commandUid)
        {
            ESRI.ArcGIS.Framework.ICommandBars commandBars = application.Document.CommandBars;
            ESRI.ArcGIS.Framework.ICommandItem commandItem = commandBars.Find(commandUid, false, false);

            if (commandItem != null)
                return commandItem as ESRI.ArcGIS.Desktop.AddIns.ComboBox;

            return null;
        }

    }

}

Code for second combo-box

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Linq;

namespace ArcMapAddinCBX
{
    public class FieldsCombo : ESRI.ArcGIS.Desktop.AddIns.ComboBox
    {
        public static FieldsCombo hook;

        public FieldsCombo()
        {
            hook = this;
        }

        public void UpdateItems(string[] items)
        {
            this.Clear();
            foreach (var item in items)
                this.Add(item);
        }

        protected override void OnSelChange(int cookie)
        {
            if (cookie < 0)
                return;

            var name = this.items.Where(s => s.Cookie == cookie).FirstOrDefault().Caption;
            System.Windows.Forms.MessageBox.Show("You Selected " + name + " from the ComboBox!!");

            base.OnSelChange(cookie);
        }
    }

}

Code for the toolbar

<ESRI.Configuration xmlns="http://schemas.esri.com/Desktop/AddIns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Name>ArcMapAddinCBX</Name>
  <AddInID>{d306126e-c332-457b-804e-d944fc88a07b}</AddInID>
  <Description></Description>
  <Version>1.0</Version>
  <Image>Images\ArcMapAddinCBX.png</Image>
  <Author>Freddie</Author>
  <Company></Company>
  <Date>9/8/2016</Date>
  <Targets>
    <Target name="Desktop" version="10.4" />
  </Targets>
  <AddIn language="CLR" library="ArcMapAddinCBX.dll" namespace="ArcMapAddinCBX">
    <ArcMap>
      <Commands>
        <ComboBox id="ArcMapAddinCBX_LayerCombo" class="LayerCombo" message="List of Feature Layers in the Map" caption="Layer Combo Box" tip="Select a Feature Layer" category="Add-In Controls" image="Images\LayerCombo.png" sizeString="WWWWWWWWWWWWWWW" itemSizeString="WWWWWWWWWWWWWWW" />
        <ComboBox id="ArcMapAddinCBX_FieldsCombo" class="FieldsCombo" message="List of Fields in the Layer." caption="Fields Combo Box" tip="Select a Field Name" category="Add-In Controls" image="Images\FieldsCombo.png" sizeString="WWWWWWWWWWWWWWW" itemSizeString="WWWWWWWWWWWWWWW" />
      </Commands>
      <Toolbars>
        <Toolbar id="ArcMapAddinCBX_CBX_Toolbar" caption="CBX Toolbar" showInitially="true">
          <Items>
            <ComboBox refID="ArcMapAddinCBX_LayerCombo" />
            <ComboBox refID="ArcMapAddinCBX_FieldsCombo" separator="true" />
          </Items>
        </Toolbar>
      </Toolbars>
    </ArcMap>
  </AddIn>
</ESRI.Configuration>

Video Showing How it Works

....coming soon

Reply
0 Kudos