Layer Attributes
LayerAttributesDockWindow.cs
// Copyright 2011 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.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Linq;
using System.Windows.Forms;
using System.Collections;
using System.Collections.ObjectModel;

using ESRI.ArcGISExplorer;
using ESRI.ArcGISExplorer.Application;
using ESRI.ArcGISExplorer.Mapping;
using ESRI.ArcGISExplorer.Geometry;
using ESRI.ArcGISExplorer.Data;
using ESRI.ArcGISExplorer.Threading;

namespace LayerAttributesCS
{
  public partial class LayerAttributesDockWindow : ESRI.ArcGISExplorer.Application.DockWindow
  {
    /// <summary>
    /// The current Map.  Note that this variable will be reset in the Application_DocumentOpened
    /// when a new map is opened.
    /// </summary>
    private Map _map = null;

    /// <summary>
    /// A List of all the open LayerAttributesForm forms.
    /// </summary>
    private List<LayerAttributesForm> _openForms = new List<LayerAttributesForm>();


    /// <summary>
    /// Initializes a new instance of the LayerAttributesDockWindow class.
    /// </summary>
    public LayerAttributesDockWindow()
    {
      InitializeComponent();    
    }

    /// <summary>
    /// Handles the Load event of the AttributesDockWindow control by setting up events which
    /// a required for maintaining business logic within the addin.
    /// </summary>
    private void AttributesDockWindow_Load(object sender, EventArgs e)
    {
      ESRI.ArcGISExplorer.Application.Application.DocumentOpened += new EventHandler(Application_DocumentOpened);
      ESRI.ArcGISExplorer.Application.Application.MapItemChanged += new EventHandler<MapItemEventArgs>(Application_MapItemChanged);
 
      //won't fire first time so call it manually
      Application_DocumentOpened(null, null); 
    }

    /// <summary>
    /// Handles the double-click event of the lstFLayer Listbox by Opening a form displaying 
    /// the attributes of the selected feature layer.
    /// </summary>
    private void lstFLayers_DoubleClick(object sender, EventArgs e)
    {
      try
      {
        //Check whether an item has been selected 
        if (lstFLayers.SelectedItem != null)
        {
          //Check whether a LayerAttributesForm for this feature layer is already open
          if (IsAttributeWindowOpenForLayer((FeatureLayer)lstFLayers.SelectedItem))
          {
            //just give the form focus
            LayerAttributesForm attForm = GetOpenAttributesForm((FeatureLayer)lstFLayers.SelectedItem);
            if (attForm != null)
            {
              attForm.Focus();
            }
          }
          else
          {
            //***********************************************************************
            //Important Code - Create a new form to display the attribute information
            //***********************************************************************
            ShowAttributesForm();
          }
        }
      }
      catch (Exception ex)
      {
        MessageBox.Show("An error has occurred while showing the form: " + ex.Message,"Error",MessageBoxButtons.OK );
      }
      
    }

    /// <summary>
    /// Handles the DocumentOpened event by initializing the map variable and setting up the DocWindow display.
    /// </summary>
    void Application_DocumentOpened(object sender, EventArgs e)
    {
      
      _map = ESRI.ArcGISExplorer.Application.Application.ActiveMapDisplay.Map;
      
      SetupDisplayFeatureLayerAttributesUsage();

      //add the names of all the feature layers in the current map to the listbox
      ReadOnlyCollection<FeatureLayer> layers = _map.GetMapItems<FeatureLayer>();

      lstFLayers.Items.Clear();

      foreach (FeatureLayer fl in layers)
      {
        lstFLayers.Items.Add(fl);
      }
    }

    /// <summary>
    /// Handles the MapItemChanged event to keep the DocWindow listbox content synchronized 
    /// with the application's table of contents window.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">A MapItemEventArgs object containing the event data which includes notifications
    /// for when layers are added or removed.</param> 
    void Application_MapItemChanged(object sender, MapItemEventArgs e)
    {
        //only check map item changes involving feature layers
      if (e.MapItem is FeatureLayer)
      {
        FeatureLayer featureLayer = (FeatureLayer)e.MapItem;

        if (e.Status == MapItemChangeStatus.Added)
        {
          //a new feature layer has been added, so add it to the listbox as well
          lstFLayers.Items.Add(featureLayer);
        }
        else if ((e.Status == MapItemChangeStatus.Removing)  || (e.Status == MapItemChangeStatus.RemovingChild))
        {
          //A feature layer is being removed from the table of contents so close the 
          //LayerAttributesForm for this feature layer if it is open 
          foreach (LayerAttributesForm form in _openForms)
          {
            FeatureLayer fl = form.FeatureLayer;

            if (featureLayer == fl)
            {
              form.Close(); //this will cause the form_formclosing event to fire
              break;
            }
          }

          //remove it from the listbox.
          foreach (FeatureLayer listboxItem in lstFLayers.Items)
          {
            if (listboxItem == featureLayer)
            {
              lstFLayers.Items.Remove(listboxItem);
              break;
            }
          }
        }

        //refresh the list box labels if required
        SetupDisplayFeatureLayerAttributesUsage();
      }
    }

    /// <summary>
    /// Handles the FormClosing event by simply removing a reference to the form from the _openForms ArrayList
    /// </summary>
    void form_FormClosing(object sender, FormClosingEventArgs e)
    {
      LayerAttributesForm attributesForm = (LayerAttributesForm)sender;

      foreach (LayerAttributesForm foundForm in _openForms)
      {
        if (attributesForm == foundForm)
        {
          _openForms.Remove(attributesForm);
          break;
        }
      }
    }

    #region "private methods"

    /// <summary>
    /// Creates a new LayerAttributesForm for the specified feature layer, then displays it.
    /// </summary>
    private void ShowAttributesForm()
    {
      LayerAttributesForm form = new LayerAttributesForm((FeatureLayer)lstFLayers.SelectedItem);

      form.FormClosing += new FormClosingEventHandler(form_FormClosing);
      //display the form
      form.Show(ESRI.ArcGISExplorer.Application.Application.Window);

      // add form to list of open forms
      _openForms.Add(form);

    }

    /// <summary>
    /// Sets up the labels and listbox status for the doc window.
    /// </summary>
    private void SetupDisplayFeatureLayerAttributesUsage()
    {
      if (_map.GetMapItems<FeatureLayer>().Count == 0)
      {
        label1.Text = "No feature layers in map";
        label2.Text = "";
        lstFLayers.Enabled = false;
      }
      else
      {
        label1.Text = "View the attributes of a feature layer";
        label2.Text = "in the map by double clicking on the item.";
        lstFLayers.Enabled = true;
      }
    }

    /// <summary>
    /// Checks to see whether a LayerAttributesForm object already exists for this feature layer.
    /// </summary>
    /// <param name="item">A FeatureLayer</param>
    /// <returns>true if the form is found, otherwise false.</returns>
    private bool IsAttributeWindowOpenForLayer(FeatureLayer item)
    {
      bool foundAttributesForm = false;
      
      foreach (LayerAttributesForm form in _openForms)
      {
        FeatureLayer fl = form.FeatureLayer;

        if (item == fl)
        {
          foundAttributesForm = true;
          break;
        }
      }

      return foundAttributesForm;
    }

    /// <summary>
    /// Returns the attributes form for a particular feature layer.
    /// </summary>
    /// <param name="item">A FeatureLayer</param>
    /// <returns>A LayerAttributesForm object which is used to display the attribute data. 
    /// Returns null if a corresponding form is not found.</returns>
    private LayerAttributesForm GetOpenAttributesForm(FeatureLayer item)
    {     
      LayerAttributesForm openForm = null;

      foreach (LayerAttributesForm form in _openForms)
      {
        FeatureLayer fl = form.FeatureLayer;

        if (item == fl)
        {
          openForm = form;
          break;
        }
      }
      return openForm;
    }
    #endregion

  }
}