[GIS] How to query all layers in ArcMap and get access to them by name or index

arcmaparcobjectsclayersquery

I have ArcMap with tons of layers. Some of these layers may contain another layers with data (aka Composite layers) or they don't. The depth of composite layers in unknown. I need to query all layer names and put it to comboBox (done). Next step is finding selected in comboBox layer (by name? by index?) and get all its fields to another comboBox.

My problem is I can't get access to layer by name or index because they may be represented as composite layers and my method for finding layers by name or index will not work. How should I get direct access to layer or maybe create custom array with indexes and names?

Here is my code:

private List<ILayer> GetAllLayers(IMap mp, ICompositeLayer cl)
{   
    listIndexesAndNames.Add(new comboBoxLayerListItemsClass(){ItemName = "", ItemIndex = 0} );

    if (mp == null && cl == null)
    {
        return null;
    }
    //ILayer l;
    List<ILayer> listOfLayers = new List<ILayer>();
    if (mp != null && cl == null)
    {
        for (int i = 0; i < mp.LayerCount; i++)
        {
            if (mp.Layer[i] is ICompositeLayer)
            {
                cl = mp.Layer[i] as ICompositeLayer;
                GetAllLayers(null, cl);
                ++index;
                listIndexesAndNames.Add(new comboBoxLayerListItemsClass() { ItemName = mp.Layer[i].Name, ItemIndex = index });
            }
            else
            {
                listOfLayers.Add(mp.Layer[i]);
                comboBoxLayerList_Houses.Items.Add(new comboBoxLayerListItemsClass() { ItemName = mp.Layer[i].Name});
            }
        }
    }
    else if (mp == null && cl != null)
    {
        for (int i = 0; i < cl.Count; i++)
        {
            if (cl.Layer[i] is ICompositeLayer)
            {
                ICompositeLayer cl2 = (ICompositeLayer)cl.Layer[i];
                GetAllLayers(null, cl2);
            }
            else
            {
                listOfLayers.Add(cl.Layer[i]);
                comboBoxLayerList_Houses.Items.Add(new comboBoxLayerListItemsClass() { ItemName = cl.Layer[i].Name });
            }
        }
    }
    return listOfLayers;
}

Best Answer

I am going to write this in VB.Net since that is what I know, and hopefully you can figure out the C# way to do it:

To find all the layers, use IEnumLayer interface:

Dim pEnumLayer As IEnumLayer = My.ArcMap.Document.ActiveView.FocusMap.Layers(Nothing, True)

The second argument determines if this drills down into composite layers.

To get the layer from the chosen item in the combobox, save all the layers returned from pEnumLayer into a list of IDataset, making sure the layer is also ITable and that it is not IRasterLayer:

Dim MapLayers As New List(Of IDataset)
pEnumLayer.Reset()
Dim pLayer As ILayer = pEnumLayer.Next()
Do Until pLayer Is Nothing
    If TypeOf pLayer Is ITable And Not TypeOf pLayer Is IRasterLayer Then
        Dim pDataset As IDataset = pLayer
        MapLayers.Add(pDataset)
    End If
    pLayer = pEnumLayer.Next()
Loop

Then set the datasource of the combobox to be the MapLayers list and set the display member to be the IDataset.Name method:

LayersComboBox.DataSource = MapLayers
LayersComboBox.DisplayMember = ".Name"

This will show the name of each layer in the combo box.

To get the fields, pass the LayersComboBox.SelectedItem (which is as IDataset), and add the field name to the fields combo box items. You'll probably want to put this code in the SelectIndexChanged function for the LayersComboBox:

FieldsComboBox.Items.Clear()
Dim pTable As ITable = LayersComboBox.SelectedItem
Dim pFields As IFields = pTable.Fields
For i = 0 To pFields.FieldCount - 1
    FieldsComboBox.Items.Add(pFields.Field(i).Name)
Next
Related Question