Implementing schematic containers around schematic features
StationsInContainers.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 ESRI.ArcGIS.Schematic;
using Microsoft.VisualBasic;

namespace ContainerManagerCS
{
  public class StationsInContainers : ESRI.ArcGIS.Desktop.AddIns.Extension
  {
    //The OnAfterLoadDiagram is used to define the relations between elements
    //contained in a diagram. It is called by the AfterLoadDiagram 
    //event defined in the schematic project. The diagram contains Stations and 
    //Containers elements. For the Station element type, a particular attribute 
    //named RelatedFeeder has been created. This attribute is used to identify 
    //the container the station is related to. Near the top of the procedure, 
    //a new schematic relation is created (SchematicContainerManager). The 
    //ISchematicRelationControllerEdit CreateRelation method is used to specify 
    //that the station is related to its container. The value set for the 
    //RelatedFeeder attribute specifies whether or not the station is related 
    //to a container.

    private SchematicDatasetManager m_DatasetMgr;

    public StationsInContainers()
    {
    }

    protected override void OnStartup()
    {
      m_DatasetMgr = new SchematicDatasetManager();
      m_DatasetMgr.AfterLoadDiagram += new ISchematicDatasetEvents_AfterLoadDiagramEventHandler(OnAfterLoadDiagram);
      m_DatasetMgr.AfterRefreshDiagram+=new ISchematicDatasetEvents_AfterRefreshDiagramEventHandler(OnAfterRefreshDiagram);
    }

    protected override void OnShutdown()
    {
      m_DatasetMgr.AfterLoadDiagram -= OnAfterLoadDiagram;
      m_DatasetMgr.AfterRefreshDiagram -= OnAfterRefreshDiagram;
      m_DatasetMgr = null;
    }

    public void OnAfterLoadDiagram(ESRI.ArcGIS.Schematic.ISchematicInMemoryDiagram inMemoryDiagram)
    {
      if (State != ESRI.ArcGIS.Desktop.AddIns.ExtensionState.Enabled) return;

      ISchematicElementClass schemContainerClass = null;
      ISchematicElementClass schemElementClass;
      ISchematicElementClass schemStationClass = null;
      IEnumSchematicInMemoryFeature enumElementsInContainer;
      IEnumSchematicInMemoryFeature enumContainerElements;
      ISchematicInMemoryFeature schemFeature = null;
      ISchematicInMemoryFeature schemContainerFeature = null;
      object feederOID;
      string containerNameID;
      IEnumSchematicElementClass enumElementClass;
      ISchematicAttributeContainer schemAttributeContainer;
      ISchematicAttribute schemAttributeRelatedFeeder;
      //ISchematicElement schemElement ;
      ISchematicRelationController schemRelationController = null;
      ISchematicRelationControllerEdit schemRelationControllerEdit = null;
      Collection colContElem = new Collection();

      // Getting SchematicFeature Class Stations and Containers
      enumElementClass = inMemoryDiagram.SchematicDiagramClass.AssociatedSchematicElementClasses;
      enumElementClass.Reset();
      schemElementClass = enumElementClass.Next();

      while (schemElementClass != null)
      {
        if (schemElementClass.Name == "Stations")
          schemStationClass = schemElementClass;
        if (schemElementClass.Name == "Containers")
          schemContainerClass = schemElementClass;
        if (schemStationClass != null && schemContainerClass != null)
          break;

        schemElementClass = enumElementClass.Next();
      }
      // go out if schemStationClass or schemContainerClass are null
      if (schemStationClass == null || schemContainerClass == null)
        return;

      // Getting the Stations elements that will be displayed in the containers
      enumElementsInContainer = inMemoryDiagram.GetSchematicInMemoryFeaturesByClass(schemStationClass);
      if (enumElementsInContainer == null)
        return;

      // Creating the Schematic Container Manager
      schemRelationController = new SchematicRelationController();

      // Creating the Schematic Container Editor that will be used to define the relation between the stations and their container
      schemRelationControllerEdit = (ISchematicRelationControllerEdit)schemRelationController;

      // Defining each Container element as a schematic container
      enumContainerElements = inMemoryDiagram.GetSchematicInMemoryFeaturesByClass(schemContainerClass);

      // Add Container Element to a collection
      enumContainerElements.Reset();
      schemContainerFeature = enumContainerElements.Next();
      while (schemContainerFeature != null)
      {
        colContElem.Add(schemContainerFeature, schemContainerFeature.Name, null, null);
        schemContainerFeature = enumContainerElements.Next();
      }

      // Setting the relation between each station and its related container
      enumElementsInContainer.Reset();
      schemFeature = enumElementsInContainer.Next();

      while (schemFeature != null)
      {
        // The relation is specified by the RelatedFeeder attribute value defined for each station
        schemAttributeContainer = (ISchematicAttributeContainer)schemFeature.SchematicElementClass;
        schemAttributeRelatedFeeder = schemAttributeContainer.GetSchematicAttribute("RelatedFeeder", false);

        feederOID = schemAttributeRelatedFeeder.GetValue((ISchematicObject)schemFeature);

        if (feederOID != null)
        {
          containerNameID = "Container-" + feederOID.ToString();

          try
          {
            // Retrieve Container Element in the collection
            schemContainerFeature = (ISchematicInMemoryFeature)colContElem[containerNameID];
            // Create relation
            schemRelationControllerEdit.CreateRelation(schemFeature, schemContainerFeature);
          }
          catch { }
        }

        schemContainerFeature = null;
        schemFeature = enumElementsInContainer.Next();
      }
    }

    public void OnAfterRefreshDiagram(ESRI.ArcGIS.Schematic.ISchematicInMemoryDiagram inMemoryDiagram)
    {
      OnAfterLoadDiagram(inMemoryDiagram);
    }

  }

}