[GIS] Using IFeature Selection with ArcObjects and C#

arcgis-10.0arcobjectsc

I have a list of IFeature (List lst) and I want to select and highlight and show in the map. All I am getting is like the IFeatureSelection , ISelectionSet and they work with Feature Layer not the feature. Can anyone show me some light in that direction. Regarding the context, I am getting the features from a method after validations and I am trying to select those/ or highlight those.

public void HighlightInvalidFeatures(List<IFeature> featureList, IActiveView activeView, IGeometry geometry , IMap map)
        {
            //First find all the feature classes that exist for your features
            Dictionary<IFeatureClass, List<int>> uniqueFeatureClasses = new Dictionary<IFeatureClass, List<int>>();
            IFeatureClass fc = null;
            foreach (var feature in featureList)
            {
                fc = feature.Table as IFeatureClass;

                if (!uniqueFeatureClasses.ContainsKey(fc))
                    uniqueFeatureClasses.Add(fc, new List<int>());

                uniqueFeatureClasses[fc].Add(feature.OID);
            }

            //get the current map object
            IMap mapInstance = map;

            //clear the current selection
            mapInstance.ClearSelection();

            IFeatureLayer fLayer = null;

            IQueryFilter filter = null;
            //create and add the layers
            foreach (var pair in uniqueFeatureClasses)
            {
                //create the FeatureLayer
                fLayer = new FeatureLayerClass();
                fLayer.FeatureClass = pair.Key;
                fLayer.Name = pair.Key.AliasName; //this could be anything



         IEnumLayer enumLayer = mapInstance.get_Layers(null, true);
                 ILayer esriLayer = null;
                 while ((esriLayer=enumLayer.Next()) != null)
                {
                     // Check this if part
                        if (esriLayer.Valid)
                        {
                                if (esriLayer == featureLayer)
                                {
                        fLayer = esriLayer;

                                }
                    else
                    {
                        // Adding the layer 
                        mapInstance.AddLayer(fLayer as ILayer);
                    }
                        }
                }

                //select on the layer
                filter = new QueryFilter();
                filter.WhereClause = pair.Key.OIDFieldName + " IN (" + String.Join(",", pair.Value) + ")";

                // filter.WhereClause = fc.OIDFieldName + " IN (" + String.Join(",", pair.Value) + ")";

                activeView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, activeView.FocusMap, null);

                (fLayer as IFeatureSelection).SelectFeatures(filter, esriSelectionResultEnum.esriSelectionResultAdd, false);

                activeView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, activeView.FocusMap, null);
            }   

        }
        #endregion
    }

Best Answer

There may be better ways of doing this, but this is how I'd do it off the top of my head.

//First find all the feature classes that exist for your features
Dictionary<IFeatureClass, List<int>> uniqueFeatureClasses= new Dictionary<IFeatureClass, List<int>>();
foreach(var feature in MyListOfFeatures)
{   
    IFeatureClass fc = feature.Table as IFeatureClass;

    if(!uniqueFeatureClasses.ContainsKey(fc))
        uniqueFeatureClasses.Add(fc, new List<int>());

    uniqueFeatureClasses[fc].Add(feature.OID);
}

//get the current map object
IMap map = (ArcMap.Application.Document as IMxDocument).FocusMap;

//clear the current selection
map.ClearSelection();

//create and add the layers
foreach(var pair in uniqeFeatureClasses)
{
    //create the FeatureLayer
    IFeatureLayer fLayer = new IFeatureLayer();
    fLayer.FeatureClass = pair.Key;
    fLayer.Name = pair.Key.AliasName; //this could be anything
    map.AddLayer(fLayer as ILayer);

    //select on the layer
    IQueryFilter filter = new QueryFilter();
    filter.WhereClause = fc.OIDFieldName + " IN (" + String.Join(",",pair.Value) + ")";

    (fLayer as IFeatureSelection).SelectFeatures(filter, esriSelectionResultEnum.esriSelectionResultAdd, false);
}

Update:

I have tried your code and with a small modification it works (at least as far as I understand what you are trying to do). The issue is that comparing Layers against each other just doesn't work super well. So I changed this:

if (esriLayer == featureLayer)
{
    fLayer = esriLayer;
}

to this:

if (fLayer.FeatureClass == (esriLayer as IFeatureLayer).FeatureClass)
{
   fLayer = (esriLayer as IFeatureLayer); 
}

After I made that change I input features into the method from several layers and all of those features were highlighted at once.

Related Question