ArcObjects Library Reference  

SelectionExtension

About the Create a custom selection extension by extending ArcObjects Sample

[C#]

SelectionExtension.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Framework;
using ESRI.ArcGIS.ADF.CATIDs;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.ArcMapUI;

namespace SelectionCOMSample
{
  [Guid("c1537917-5ca0-4637-9728-a76b70517545")]
  [ClassInterface(ClassInterfaceType.None)]
  [ProgId("SelectionCOMSample.SelectionExtension")]
  public class SelectionExtension : IExtension, IExtensionConfig
  {
    #region COM Registration Function(s)
    [ComRegisterFunction()]
    [ComVisible(false)]
    static void RegisterFunction(Type registerType)
    {
      // Required for ArcGIS Component Category Registrar support
      ArcGISCategoryRegistration(registerType);

      //
      // TODO: Add any COM registration code here
      //
    }

    [ComUnregisterFunction()]
    [ComVisible(false)]
    static void UnregisterFunction(Type registerType)
    {
      // Required for ArcGIS Component Category Registrar support
      ArcGISCategoryUnregistration(registerType);

      //
      // TODO: Add any COM unregistration code here
      //
    }

    #region ArcGIS Component Category Registrar generated code
    /// <summary>
    /// Required method for ArcGIS Component Category registration -
    /// Do not modify the contents of this method with the code editor.
    /// </summary>
    private static void ArcGISCategoryRegistration(Type registerType)
    {
      string regKey = string.Format("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID);
      MxExtension.Register(regKey);

    }
    /// <summary>
    /// Required method for ArcGIS Component Category unregistration -
    /// Do not modify the contents of this method with the code editor.
    /// </summary>
    private static void ArcGISCategoryUnregistration(Type registerType)
    {
      string regKey = string.Format("HKEY_CLASSES_ROOT\\CLSID\\{{{0}}}", registerType.GUID);
      MxExtension.Unregister(regKey);

    }

    #endregion
    #endregion
    private IApplication m_application;
    private esriExtensionState m_enableState;
    private static IDockableWindow s_dockWindow;
    private static SelectionExtension s_extension;
    private bool m_hasSelectableLayer;
    private IMap m_map;
    private IMxDocument m_doc;

    public SelectionExtension()
    {
      s_extension = this;
    }
    #region IExtension Members

    /// <summary>
    /// Name of extension. Do not exceed 31 characters
    /// </summary>
    public string Name
    {
      get
      {
        return "ESRI_SelectionCOMSample_SelectionExtension";
      }
    }

    public void Shutdown()
    {
      m_application = null;
    }

    public void Startup(ref object initializationData)
    {
      m_application = initializationData as IApplication;
      if (m_application == null)
        return;

      m_doc = m_application.Document as IMxDocument;

      //Get dockable window.
      IDockableWindowManager dockableWindowManager = m_application as IDockableWindowManager;
      UID dockWinID = new UIDClass();
      dockWinID.Value = @"SelectionCOMSample.SelectionCountDockWin";
      s_dockWindow = dockableWindowManager.GetDockableWindow(dockWinID);

      //Wire up events.
      IDocumentEvents_Event docEvents = m_doc as IDocumentEvents_Event;
      docEvents.NewDocument += new ESRI.ArcGIS.ArcMapUI.IDocumentEvents_NewDocumentEventHandler(ArcMap_NewOpenDocument);
      docEvents.OpenDocument += new ESRI.ArcGIS.ArcMapUI.IDocumentEvents_OpenDocumentEventHandler(ArcMap_NewOpenDocument);

    }

    #endregion

    internal IDockableWindow GetSelectionCountWindow
    {
      get
      {
        return s_dockWindow;
      }
    }

    internal static SelectionExtension GetExtension()
    {
      return s_extension;
    }

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

      Initialize();
    }

    private void Initialize()
    {
      //Reset event handlers.
      IActiveViewEvents_Event avEvent = m_doc.FocusMap as IActiveViewEvents_Event;
      avEvent.ItemAdded += new IActiveViewEvents_ItemAddedEventHandler(AvEvent_ItemAdded);
      avEvent.ItemDeleted += new IActiveViewEvents_ItemDeletedEventHandler(AvEvent_ItemAdded);
      avEvent.SelectionChanged += new IActiveViewEvents_SelectionChangedEventHandler(UpdateSelCountDockWin);
      avEvent.ContentsChanged += new IActiveViewEvents_ContentsChangedEventHandler(avEvent_ContentsChanged);
      //Update the UI.
      m_map = m_doc.FocusMap;
      FillComboBox();
      UpdateSelCountDockWin();
      m_hasSelectableLayer = CheckForSelectableLayer();
    }

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

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

    private void AVEvents_FocusMapChanged()
    {
      Initialize();
    }

    private void UpdateSelCountDockWin()
    {
      // Update the contents of the lsitView, when the selection changes in the map. 
      IFeatureLayer featureLayer;
      IFeatureSelection featSel;

      SelectionCountDockWin.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;
          SelectionCountDockWin.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 = m_doc.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;
    }
    internal bool IsExtensionEnabled
    {
      get
      {
        return this.State == esriExtensionState.esriESEnabled;
      }
    }

    internal bool HasSelectableLayer()
    {
      return m_hasSelectableLayer;
    }


    #region IExtensionConfig Members

    public string Description
    {
      get
      {
        return "SelectionExtension\r\n" +
            "Copyright ? ESRI 2009\r\n\r\n" +
            "This extension is a selection sample extension in C#.";
      }
    }

    /// <summary>
    /// Friendly name shown in the Extension dialog
    /// </summary>
    public string ProductName
    {
      get
      {
        return "Selection Sample Extension";
      }
    }

    public esriExtensionState State
    {
      get
      {
        return m_enableState;
      }
      set
      {
        if (m_enableState != 0 && value == m_enableState)
          return;

        //Check if ok to enable or disable extension
        esriExtensionState requestState = value;
        if (requestState == esriExtensionState.esriESEnabled)
        {
          //Cannot enable if it's already in unavailable state
          if (m_enableState == esriExtensionState.esriESUnavailable)
          {
            throw new COMException("Cannot enable extension");
          }

          //Determine if state can be changed
          esriExtensionState checkState = StateCheck(true);
          m_enableState = checkState;
        }
        else if (requestState == 0 || requestState == esriExtensionState.esriESDisabled)
        {
          //Determine if state can be changed
          esriExtensionState checkState = StateCheck(false);
          if (checkState != m_enableState)
            m_enableState = checkState;
        }

      }
    }

    #endregion

    /// <summary>
    /// Determine extension state 
    /// </summary>
    /// <param name="requestEnable">true if to enable; false to disable</param>
    private esriExtensionState StateCheck(bool requestEnable)
    {
      //TODO: Replace with advanced extension state checking if needed
      //Turn on or off extension directly
      if (requestEnable)
        return esriExtensionState.esriESEnabled;
      else
        return esriExtensionState.esriESDisabled;
    }
  }
}
[Visual Basic .NET]

SelectionExtension.vb

Imports Microsoft.VisualBasic
Imports System
Imports System.Collections.Generic
Imports System.Text
Imports System.Runtime.InteropServices
Imports ESRI.ArcGIS.esriSystem
Imports ESRI.ArcGIS.Framework
Imports ESRI.ArcGIS.ADF.CATIDs
Imports ESRI.ArcGIS.Carto
Imports ESRI.ArcGIS.ArcMapUI

Namespace SelectionCOMSample
  <Guid("c1537917-5ca0-4637-9728-a76b70517545"), ClassInterface(ClassInterfaceType.None), ProgId("SelectionCOMSample.SelectionExtension")> _
  Public Class SelectionExtension
	  Implements IExtension, IExtensionConfig
	#Region "COM Registration Function(s)"
	<ComRegisterFunction(), ComVisible(False)> _
	Private Shared Sub RegisterFunction(ByVal registerType As Type)
	  ' Required for ArcGIS Component Category Registrar support
	  ArcGISCategoryRegistration(registerType)

	  '
	  ' TODO: Add any COM registration code here
	  '
	End Sub

	<ComUnregisterFunction(), ComVisible(False)> _
	Private Shared Sub UnregisterFunction(ByVal registerType As Type)
	  ' Required for ArcGIS Component Category Registrar support
	  ArcGISCategoryUnregistration(registerType)

	  '
	  ' TODO: Add any COM unregistration code here
	  '
	End Sub

	#Region "ArcGIS Component Category Registrar generated code"
	''' <summary>
	''' Required method for ArcGIS Component Category registration -
	''' Do not modify the contents of this method with the code editor.
	''' </summary>
	Private Shared Sub ArcGISCategoryRegistration(ByVal registerType As Type)
	  Dim regKey As String = String.Format("HKEY_CLASSES_ROOT\CLSID\{{{0}}}", registerType.GUID)
	  MxExtension.Register(regKey)

	End Sub
	''' <summary>
	''' Required method for ArcGIS Component Category unregistration -
	''' Do not modify the contents of this method with the code editor.
	''' </summary>
	Private Shared Sub ArcGISCategoryUnregistration(ByVal registerType As Type)
	  Dim regKey As String = String.Format("HKEY_CLASSES_ROOT\CLSID\{{{0}}}", registerType.GUID)
	  MxExtension.Unregister(regKey)

	End Sub

	#End Region
	#End Region
	Private m_application As IApplication
	Private m_enableState As esriExtensionState
	Private Shared s_dockWindow As IDockableWindow
	Private Shared s_extension As SelectionExtension
	Private m_hasSelectableLayer As Boolean
	Private m_map As IMap
	Private m_doc As IMxDocument

	Public Sub New()
	  s_extension = Me
	End Sub
	#Region "IExtension Members"

	''' <summary>
	''' Name of extension. Do not exceed 31 characters
	''' </summary>
	Public ReadOnly Property Name() As String Implements IExtension.Name
	  Get
		Return "ESRI_SelectionCOMSample_SelectionExtension"
	  End Get
	End Property

	Public Sub Shutdown() Implements IExtension.Shutdown
	  m_application = Nothing
	End Sub

	Public Sub Startup(ByRef initializationData As Object) Implements IExtension.Startup
	  m_application = TryCast(initializationData, IApplication)
	  If m_application Is Nothing Then
		Return
	  End If

	  m_doc = TryCast(m_application.Document, IMxDocument)

	  'Get dockable window.
	  Dim dockableWindowManager As IDockableWindowManager = TryCast(m_application, IDockableWindowManager)
	  Dim dockWinID As UID = New UIDClass()
	  dockWinID.Value = "SelectionCOMSample.SelectionCountDockWin"
	  s_dockWindow = dockableWindowManager.GetDockableWindow(dockWinID)

	  'Wire up events.
	  Dim docEvents As IDocumentEvents_Event = TryCast(m_doc, IDocumentEvents_Event)
	  AddHandler docEvents.NewDocument, AddressOf ArcMap_NewOpenDocument
	  AddHandler docEvents.OpenDocument, AddressOf ArcMap_NewOpenDocument

	End Sub

	#End Region

	Friend ReadOnly Property GetSelectionCountWindow() As IDockableWindow
	  Get
		Return s_dockWindow
	  End Get
	End Property

	Friend Shared Function GetExtension() As SelectionExtension
	  Return s_extension
	End Function

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

	  Initialize()
	End Sub

	Private Sub Initialize()
	  'Reset event handlers.
	  Dim avEvent As IActiveViewEvents_Event = TryCast(m_doc.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 = m_doc.FocusMap
	  FillComboBox()
	  UpdateSelCountDockWin()
	  m_hasSelectableLayer = CheckForSelectableLayer()
	End Sub

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

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

	Private Sub AVEvents_FocusMapChanged()
	  Initialize()
	End Sub

	Private Sub UpdateSelCountDockWin()
	  ' Update the contents of the lsitView, when the selection changes in the map. 
	  Dim featureLayer As IFeatureLayer
	  Dim featSel As IFeatureSelection

	  SelectionCountDockWin.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
		  SelectionCountDockWin.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 = m_doc.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
	Friend ReadOnly Property IsExtensionEnabled() As Boolean
	  Get
		Return Me.State = esriExtensionState.esriESEnabled
	  End Get
	End Property

	Friend Function HasSelectableLayer() As Boolean
	  Return m_hasSelectableLayer
	End Function


	#Region "IExtensionConfig Members"

	Public ReadOnly Property Description() As String Implements IExtensionConfig.Description
	  Get
        Return "SelectionExtension" & Constants.vbCrLf & "Copyright ? ESRI 2009" & Constants.vbCrLf & Constants.vbCrLf & "This extension is a selection sample extension in VB.NET."
	  End Get
	End Property

	''' <summary>
	''' Friendly name shown in the Extension dialog
	''' </summary>
	Public ReadOnly Property ProductName() As String Implements IExtensionConfig.ProductName
	  Get
		Return "Selection Sample Extension"
	  End Get
	End Property

	Public Property State() As esriExtensionState Implements IExtensionConfig.State
	  Get
		Return m_enableState
	  End Get
	  Set(ByVal value As esriExtensionState)
		If m_enableState <> 0 AndAlso value = m_enableState Then
		  Return
		End If

		'Check if ok to enable or disable extension
		Dim requestState As esriExtensionState = value
		If requestState = esriExtensionState.esriESEnabled Then
		  'Cannot enable if it's already in unavailable state
		  If m_enableState = esriExtensionState.esriESUnavailable Then
			Throw New COMException("Cannot enable extension")
		  End If

		  'Determine if state can be changed
		  Dim checkState As esriExtensionState = StateCheck(True)
		  m_enableState = checkState
		ElseIf requestState = 0 OrElse requestState = esriExtensionState.esriESDisabled Then
		  'Determine if state can be changed
		  Dim checkState As esriExtensionState = StateCheck(False)
		  If checkState <> m_enableState Then
			m_enableState = checkState
		  End If
		End If

	  End Set
	End Property

	#End Region

	''' <summary>
	''' Determine extension state 
	''' </summary>
	''' <param name="requestEnable">true if to enable; false to disable</param>
	Private Function StateCheck(ByVal requestEnable As Boolean) As esriExtensionState
	  'TODO: Replace with advanced extension state checking if needed
	  'Turn on or off extension directly
	  If requestEnable Then
		Return esriExtensionState.esriESEnabled
	  Else
		Return esriExtensionState.esriESDisabled
	  End If
	End Function
  End Class
End Namespace