Server spatial query server object extension
SpatialQuerySOE.ArcCatalog_CSharp\PropertyForm.cs
// Copyright 2010 ESRI
// 
// All rights reserved under the copyright laws of the United States
// and applicable international laws, treaties, and conventions.
// 
// You may freely redistribute and use this sample code, with or
// without modification, provided you include the original copyright
// notice and use restrictions.
// 
// See the use restrictions.
// 

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;

namespace SpatialQuerySOE.ArcCatalog
{
    /// <summary>
    /// Defines the UI for the Spatial Query SOE
    /// </summary>
    public partial class PropertyForm : Form
    {
        #region Member Variables

        // The current SOE layer
        private string m_layer;

        // Current SOE field
        private string m_field;

        // Tracks whether the form is initializing
        private bool m_init = false;

        private System.Collections.Generic.Dictionary<string, string[]> m_fieldsDictionary = 
            new System.Collections.Generic.Dictionary<string,string[]>();

        #endregion

        #region Constructor

        public PropertyForm()
        {
            InitializeComponent();

            // Get ArcCatalog's representation of the map service being modified
            System.Type type = System.Type.GetTypeFromCLSID(typeof(ESRI.ArcGIS.Framework.AppRefClass).GUID);
            ESRI.ArcGIS.CatalogUI.IGxApplication gxApp = Activator.CreateInstance(type) as ESRI.ArcGIS.CatalogUI.IGxApplication;
            ESRI.ArcGIS.Catalog.IGxAGSObject gxAgsObj = gxApp.SelectedObject as ESRI.ArcGIS.Catalog.IGxAGSObject;

            // If the service is not stopped, disable the layers and fields drop-down lists so that the SOE cannot be configured
            if (gxAgsObj.Status != "Stopped")
            {
                ComboLayers.Enabled = false;
                ComboFields.Enabled = false;
            }
        }

        #endregion

        #region Internal Properties - getHWnd, Layer, Field, PageSite

        /// <summary>
        /// The form's handle
        /// </summary>
        internal int getHWnd()
        {
            return this.Handle.ToInt32();
        }

        /// <summary>
        /// The currently selected layer
        /// </summary>
        internal string Layer
        {  
            get { return m_layer; }
            set { m_layer = value; }
        }

        /// <summary>
        /// The currently selected field
        /// </summary>
        internal string Field
        {
            get { return m_field; }
            set { m_field = value; }
        }

        /// <summary>
        /// The PageSite of the IComPropertyPage object using the form.  Allows the form to report when its contents have changed.
        /// </summary>
        internal ESRI.ArcGIS.Framework.IComPropertyPageSite PageSite { private get; set; }

        #endregion

        #region Internal Methods - SetMap

        /// <summary>
        /// Sets the map used to populate the layers and fields drop-down lists
        /// </summary>
        /// <param name="filePath">the path to the map document</param>
        internal void SetMap(string filePath)
        {
            // Open the map document
            ESRI.ArcGIS.Carto.IMapDocument mapDocument = new ESRI.ArcGIS.Carto.MapDocumentClass();
            mapDocument.Open(filePath, null);

            // The call to get_Map() will create a lock (ldb) on a personal gdb.  Make sure ArcCatalog user and 
            // ArcGIS Server container account has read\write access to data location.  If not,
            // feature classes in the personal gdb may not be accessible (or visible in the map).
            ESRI.ArcGIS.Carto.IMap map = mapDocument.get_Map(0);

            // Get IGeoFeatureLayers from the map
            ESRI.ArcGIS.esriSystem.UID id = new ESRI.ArcGIS.esriSystem.UIDClass();
            id.Value = "{E156D7E5-22AF-11D3-9F99-00C04F6BC78E}";
            ESRI.ArcGIS.Carto.IEnumLayer enumLayer = map.get_Layers(id, true);

            int selectedIndex = 0;
            string[] fieldNames = null;
            m_fieldsDictionary.Clear();
            // Add the names of simple polygon feature layers to the layers drop-down and store the names
            // of each layer's fields in a dictionary
            ESRI.ArcGIS.Carto.IFeatureLayer featureLayer = null;
            while ((featureLayer = enumLayer.Next() as ESRI.ArcGIS.Carto.IFeatureLayer) != null)
            {
                if (featureLayer.FeatureClass.ShapeType == ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolygon &&
                featureLayer.FeatureClass.FeatureType == ESRI.ArcGIS.Geodatabase.esriFeatureType.esriFTSimple)
                    ComboLayers.Items.Add(featureLayer.Name);

                if (featureLayer.Name == m_layer)
                    selectedIndex = ComboLayers.Items.Count - 1;

                fieldNames = new string[featureLayer.FeatureClass.Fields.FieldCount];
                for (int i = 0; i < fieldNames.Length; i++)
                    fieldNames[i] = featureLayer.FeatureClass.Fields.get_Field(i).Name;

                m_fieldsDictionary.Add(featureLayer.Name, fieldNames);
            }

            mapDocument.Close();
            mapDocument = null;
            map = null;

            // Toggle the init flag and initialize the layers drop-down to show the current SOE layer.  Init is used
            // to prevent the drop-down's SelectedIndexChanged logic from setting m_field during initialization.
            m_init = true;
            ComboLayers.SelectedIndex = selectedIndex;
        }

        #endregion

        #region Control Event Handlers - ComboLayers_SelectedIndexChanged, ComboFields_SelectedIndexChanged, PropertyForm_FormClosed

        // Fires when a new item is selected from the layers drop-down
        private void ComboLayers_SelectedIndexChanged(object sender, EventArgs e)
        {
            m_layer = ComboLayers.Text;

            ComboFields.Items.Clear();

            // Add the fields for the currently selected layer to the fields drop-down
            int selectedIndex = 0;
            string[] fieldNames = m_fieldsDictionary[m_layer];
            for (int i = 0; i < fieldNames.Length; i++)
            {
                ComboFields.Items.Add(fieldNames[i]);

                // Get the index of the current field if the method is executing during initialization and
                // the current field match's the SOE field
                if (m_init && fieldNames[i] == m_field)
                    selectedIndex = ComboFields.Items.Count - 1;
            }

            // Update the field and layer properties if executing during initialization.  Otherwise, toggle the
            // init boolean to indicate initialization is complete.
            if (m_init)
                m_init = false;

            // Set the fields drop-down to show the current SOE field.
            ComboFields.SelectedIndex = selectedIndex;
        }

        // Fires when a new item is selected from the fields drop-down
        private void ComboFields_SelectedIndexChanged(object sender, EventArgs e)
        {
            // Update the current SOE field
            m_field = ComboFields.Text;

            // Notify ArcCatalog that the properties have changed
            this.PageSite.PageChanged();
        }

        #endregion
    }
}