ArcObjects Library Reference  

SelectionExtension

About the Custom selection extension Sample

[C#]

SelectionExtension.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using ESRI.ArcGIS.Framework;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Desktop.AddIns;

namespace SelectionSample
{
  public class SelectionExtension : ESRI.ArcGIS.Desktop.AddIns.Extension
  {
    private IMap m_map;
    private bool m_hasSelectableLayer;
    private static IDockableWindow s_dockWindow;
    private static SelectionExtension s_extension;

    // Overrides

    protected override void OnStartup()
    {
      s_extension = this;

      // Wire up events
      ArcMap.Events.NewDocument += ArcMap_NewOpenDocument;
      ArcMap.Events.OpenDocument += ArcMap_NewOpenDocument;

      Initialize();
    }

    protected override void OnShutdown()
    {
      Uninitialize();
      
      ArcMap.Events.NewDocument -= ArcMap_NewOpenDocument;
      ArcMap.Events.OpenDocument -= ArcMap_NewOpenDocument;

      m_map = null;
      s_dockWindow = null;
      s_extension = null;

      base.OnShutdown();
    }

    protected override bool OnSetState(ExtensionState state)
    {
      // Optionally check for a license here
      this.State = state;

      if (state == ExtensionState.Enabled)
        Initialize();
      else
        Uninitialize();

      return base.OnSetState(state);
    }

    protected override ExtensionState OnGetState()
    {
      return this.State;
    }

    // Privates
    private void Initialize()
    {
      // If the extension hasn't been started yet or it's been turned off, bail
      if (s_extension == null || this.State != ExtensionState.Enabled)
        return;

      // Reset event handlers
      IActiveViewEvents_Event avEvent = ArcMap.Document.FocusMap as IActiveViewEvents_Event;
      avEvent.ItemAdded += AvEvent_ItemAdded;
      avEvent.ItemDeleted += AvEvent_ItemAdded;
      avEvent.SelectionChanged += UpdateSelCountDockWin;
      avEvent.ContentsChanged += avEvent_ContentsChanged;
      
      // Update the UI
      m_map = ArcMap.Document.FocusMap;
      FillComboBox();
      SelCountDockWin.SetEnabled(true);
      UpdateSelCountDockWin();
      m_hasSelectableLayer = CheckForSelectableLayer();
    }

    private void Uninitialize()
    {
      if (s_extension == null)
        return;

      // Detach event handlers
      IActiveViewEvents_Event avEvent = m_map as IActiveViewEvents_Event;
      avEvent.ItemAdded -= AvEvent_ItemAdded;
      avEvent.ItemDeleted -= AvEvent_ItemAdded;
      avEvent.SelectionChanged -= UpdateSelCountDockWin;
      avEvent.ContentsChanged -= avEvent_ContentsChanged;
      avEvent = null;

      // Update UI
      SelectionTargetComboBox selCombo = SelectionTargetComboBox.GetSelectionComboBox();
      if (selCombo != null)
        selCombo.ClearAll();

      SelCountDockWin.SetEnabled(false);
    }

    private void UpdateSelCountDockWin()
    {
      // If the dockview hasn't been created yet
      if (!SelCountDockWin.Exists)
        return; 

      // Update the contents of the listView, when the selection changes in the map. 
      IFeatureLayer featureLayer;
      IFeatureSelection featSel;

      SelCountDockWin.Clear();

      // Loop through the layers in the map and add the layer's name and
      // selection count to the list box
      for (int i = 0; i < m_map.LayerCount; i++)
      {
        if (m_map.get_Layer(i) is IFeatureSelection)
        {
          featureLayer = m_map.get_Layer(i) as IFeatureLayer;
          if (featureLayer == null)
            break;

          featSel = featureLayer as IFeatureSelection;

          int count = 0;
          if (featSel.SelectionSet != null)
            count = featSel.SelectionSet.Count;
          SelCountDockWin.AddItem(featureLayer.Name, count);
        }
      }
    }

    private void FillComboBox()
    {
      SelectionTargetComboBox selCombo = SelectionTargetComboBox.GetSelectionComboBox();
      if (selCombo == null)
        return;

      selCombo.ClearAll();

      IFeatureLayer featureLayer;
      // Loop through the layers in the map and add the layer's name to the combo box.
      for (int i = 0; i < m_map.LayerCount; i++)
      {
        if (m_map.get_Layer(i) is IFeatureSelection)
        {
          featureLayer = m_map.get_Layer(i) as IFeatureLayer;
          if (featureLayer == null)
            break;

          selCombo.AddItem(featureLayer.Name, featureLayer);
        }
      }
    }

    private bool CheckForSelectableLayer()
    {
      IMap map = ArcMap.Document.FocusMap;
      // Bail if map has no layers
      if (map.LayerCount == 0)
        return false;

      // Fetch all the feature layers in the focus map
      // and see if at least one is selectable
      UIDClass uid = new UIDClass();
      uid.Value = "{40A9E885-5533-11d0-98BE-00805F7CED21}";
      IEnumLayer enumLayers = map.get_Layers(uid, true);
      IFeatureLayer featureLayer = enumLayers.Next() as IFeatureLayer;
      while (featureLayer != null)
      {
        if (featureLayer.Selectable == true)
          return true;
        featureLayer = enumLayers.Next() as IFeatureLayer;
      }
      return false;
    }

    // Event handlers

    private void ArcMap_NewOpenDocument()
    {
      IActiveViewEvents_Event pageLayoutEvent = ArcMap.Document.PageLayout as IActiveViewEvents_Event;
      pageLayoutEvent.FocusMapChanged += new IActiveViewEvents_FocusMapChangedEventHandler(AVEvents_FocusMapChanged);

      Initialize();
    }

    private void avEvent_ContentsChanged()
    {
      m_hasSelectableLayer = CheckForSelectableLayer();
    }

    private void AvEvent_ItemAdded(object Item)
    {
      m_map = ArcMap.Document.FocusMap;
      FillComboBox();
      UpdateSelCountDockWin();
      m_hasSelectableLayer = CheckForSelectableLayer();
    }

    private void AVEvents_FocusMapChanged()
    {
      Initialize();
    }

    // Statics

    internal static IDockableWindow GetSelectionCountWindow()
    {
      if (s_extension == null)
        GetExtension();

      // Only get/create the dockable window if they ask for it
      if (s_dockWindow == null)
      {
        // Use GetDockableWindow directly intead of FromID as we want the client IDockableWindow not the internal class
        UID dockWinID = new UIDClass();
        dockWinID.Value = ThisAddIn.IDs.SelCountDockWin;
        s_dockWindow = ArcMap.DockableWindowManager.GetDockableWindow(dockWinID);
        s_extension.UpdateSelCountDockWin();
      }

      return s_dockWindow;
    }

    internal static bool IsExtensionEnabled() 
    {
      if (s_extension == null)
        GetExtension();

      if (s_extension == null)
        return false;

      return s_extension.State == ExtensionState.Enabled;
    }

    internal static bool HasSelectableLayer()
    {
      if (s_extension == null)
        GetExtension();

      if (s_extension == null)
        return false;

      return s_extension.m_hasSelectableLayer;
    }

    private static SelectionExtension GetExtension()
    {
      if (s_extension == null)
      {
        // Call FindExtension to load this just-in-time extension.
        UID id = new UIDClass();
        id.Value = ThisAddIn.IDs.SelectionExtension;
        ArcMap.Application.FindExtensionByCLSID(id);
      }

      return s_extension;
    }
  }
}

[Visual Basic .NET]

SelectionExtension.vb

Imports Microsoft.VisualBasic
Imports System
Imports System.Collections.Generic
Imports System.Text
Imports System.IO
Imports ESRI.ArcGIS.Framework
Imports ESRI.ArcGIS.esriSystem
Imports ESRI.ArcGIS.Carto
Imports ESRI.ArcGIS.Desktop.AddIns

Imports My

Namespace SelectionSample

  Public Class SelectionExtension
    Inherits ESRI.ArcGIS.Desktop.AddIns.Extension

    Private m_map As IMap
    Private m_hasSelectableLayer As Boolean
    Private Shared s_dockWindow As ESRI.ArcGIS.Framework.IDockableWindow
    Private Shared s_extension As SelectionExtension


    ' Overrides

    Protected Overrides Sub OnStartup()
      s_extension = Me

      ' Wire up events
      AddHandler ArcMap.Events.NewDocument, AddressOf ArcMap_NewOpenDocument
      AddHandler ArcMap.Events.OpenDocument, AddressOf ArcMap_NewOpenDocument

      Initialize()
    End Sub

    Protected Overloads Overrides Sub OnShutdown()
      Uninitialize()


      RemoveHandler ArcMap.Events.NewDocument, AddressOf ArcMap_NewOpenDocument
      RemoveHandler ArcMap.Events.OpenDocument, AddressOf ArcMap_NewOpenDocument

      m_map = Nothing
      s_dockWindow = Nothing
      s_extension = Nothing

      MyBase.OnShutdown()
    End Sub

    Protected Overrides Function OnSetState(ByVal state As ExtensionState) As Boolean
      ' Optionally check for a license here
      Me.State = state

      If state = ExtensionState.Enabled Then
        Initialize()
      Else
        Uninitialize()
      End If

      Return MyBase.OnSetState(state)
    End Function

    Protected Overrides Function OnGetState() As ExtensionState
      Return Me.State
    End Function

    ' Privates

    Private Sub Initialize()
      If s_extension Is Nothing Or Me.State <> ExtensionState.Enabled Then
        Return
      End If

      ' Reset event handlers
      Dim avEvent As IActiveViewEvents_Event = TryCast(ArcMap.Document.FocusMap, IActiveViewEvents_Event)
      AddHandler avEvent.ItemAdded, AddressOf AvEvent_ItemAdded
      AddHandler avEvent.ItemDeleted, AddressOf AvEvent_ItemAdded
      AddHandler avEvent.SelectionChanged, AddressOf UpdateSelCountDockWin
      AddHandler avEvent.ContentsChanged, AddressOf avEvent_ContentsChanged

      ' Update the UI
      m_map = ArcMap.Document.FocusMap
      FillComboBox()
      SelCountDockWin.SetEnabled(True)
      UpdateSelCountDockWin()
      m_hasSelectableLayer = CheckForSelectableLayer()
    End Sub

    Private Sub Uninitialize()
      If s_extension Is Nothing Then
        Return
      End If

      ' Detach event handlers
      Dim avEvent As IActiveViewEvents_Event = TryCast(m_map, IActiveViewEvents_Event)
      RemoveHandler avEvent.ItemAdded, AddressOf AvEvent_ItemAdded
      RemoveHandler avEvent.ItemDeleted, AddressOf AvEvent_ItemAdded
      RemoveHandler avEvent.SelectionChanged, AddressOf UpdateSelCountDockWin
      RemoveHandler avEvent.ContentsChanged, AddressOf avEvent_ContentsChanged
      avEvent = Nothing

      ' Update UI
      Dim selCombo As SelectionTargetComboBox = SelectionTargetComboBox.GetSelectionComboBox()
      If selCombo IsNot Nothing Then
        selCombo.ClearAll()
      End If

      SelCountDockWin.SetEnabled(False)
    End Sub

    Private Sub UpdateSelCountDockWin()
      ' If the dockview hasn't been created yet
      If (Not SelCountDockWin.Exists) Then
        Return
      End If

      ' Update the contents of the listView, when the selection changes in the map. 
      Dim featureLayer As IFeatureLayer
      Dim featSel As IFeatureSelection

      SelCountDockWin.Clear()

      ' Loop through the layers in the map and add the layer's name and
      ' selection count to the list box
      For i As Integer = 0 To m_map.LayerCount - 1
        If TypeOf m_map.Layer(i) Is IFeatureSelection Then
          featureLayer = TryCast(m_map.Layer(i), IFeatureLayer)
          If featureLayer Is Nothing Then
            Exit For
          End If

          featSel = TryCast(featureLayer, IFeatureSelection)

          Dim count As Integer = 0
          If featSel.SelectionSet IsNot Nothing Then
            count = featSel.SelectionSet.Count
          End If
          SelCountDockWin.AddItem(featureLayer.Name, count)
        End If
      Next i
    End Sub

    Private Sub FillComboBox()
      Dim selCombo As SelectionTargetComboBox = SelectionTargetComboBox.GetSelectionComboBox()
      If selCombo Is Nothing Then
        Return
      End If

      selCombo.ClearAll()

      Dim featureLayer As IFeatureLayer
      ' Loop through the layers in the map and add the layer's name to the combo box.
      For i As Integer = 0 To m_map.LayerCount - 1
        If TypeOf m_map.Layer(i) Is IFeatureSelection Then
          featureLayer = TryCast(m_map.Layer(i), IFeatureLayer)
          If featureLayer Is Nothing Then
            Exit For
          End If

          selCombo.AddItem(featureLayer.Name, featureLayer)
        End If
      Next i
    End Sub

    Private Function CheckForSelectableLayer() As Boolean
      Dim map As IMap = ArcMap.Document.FocusMap
      ' Bail if map has no layers
      If map.LayerCount = 0 Then
        Return False
      End If

      ' Fetch all the feature layers in the focus map
      ' and see if at least one is selectable
      Dim uid As New UIDClass()
      uid.Value = "{40A9E885-5533-11d0-98BE-00805F7CED21}"
      Dim enumLayers As IEnumLayer = map.Layers(uid, True)
      Dim featureLayer As IFeatureLayer = TryCast(enumLayers.Next(), IFeatureLayer)
      Do While featureLayer IsNot Nothing
        If featureLayer.Selectable = True Then
          Return True
        End If
        featureLayer = TryCast(enumLayers.Next(), IFeatureLayer)
      Loop
      Return False
    End Function

    ' Event handlers

    Private Sub ArcMap_NewOpenDocument()
      Dim pageLayoutEvent As IActiveViewEvents_Event = TryCast(ArcMap.Document.PageLayout, IActiveViewEvents_Event)
      AddHandler pageLayoutEvent.FocusMapChanged, AddressOf AVEvents_FocusMapChanged

      Initialize()
    End Sub

    Private Sub avEvent_ContentsChanged()
      m_hasSelectableLayer = CheckForSelectableLayer()
    End Sub

    Private Sub AvEvent_ItemAdded(ByVal Item As Object)
      m_map = ArcMap.Document.FocusMap
      FillComboBox()
      UpdateSelCountDockWin()
      m_hasSelectableLayer = CheckForSelectableLayer()
    End Sub

    Private Sub AVEvents_FocusMapChanged()
      Initialize()
    End Sub

    ' Statics

    Friend Shared Function GetSelectionCountWindow() As ESRI.ArcGIS.Framework.IDockableWindow
      If s_extension Is Nothing Then
        GetExtension()
      End If

      ' Only get/create the dockable window if they ask for it
      If s_dockWindow Is Nothing Then
        Dim dockWinID As UID = New UIDClass()
        dockWinID.Value = ThisAddIn.IDs.SelCountDockWin
        s_dockWindow = ArcMap.DockableWindowManager.GetDockableWindow(dockWinID)
        s_extension.UpdateSelCountDockWin()
      End If

      Return s_dockWindow
    End Function

    Friend Shared Function IsExtensionEnabled() As Boolean
      If s_extension Is Nothing Then
        GetExtension()
      End If

      If s_extension Is Nothing Then
        Return False
      End If

      Return s_extension.State = ExtensionState.Enabled
    End Function

    Friend Shared Function HasSelectableLayer() As Boolean
      If s_extension Is Nothing Then
        GetExtension()
      End If

      If s_extension Is Nothing Then
        Return False
      End If

      Return s_extension.m_hasSelectableLayer
    End Function

    Private Shared Function GetExtension() As SelectionExtension
      If s_extension Is Nothing Then
        Dim extID As UID = New UIDClass()
        extID.Value = ThisAddIn.IDs.SelectionExtension
        ' Call FindExtension to load this just-in-time extension.
        ArcMap.Application.FindExtensionByCLSID(extID)
      End If
      Return s_extension
    End Function
  End Class
End Namespace