About the Implementing a schematic layout algorithm and its layout property page Sample
[C#]
TranslateTree.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.ADF.CATIDs;
using ESRI.ArcGIS.Schematic;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
namespace ApplicativeAlgorithms
{
	[ClassInterface(ClassInterfaceType.None)]
	[Guid(TranslateTree.GUID)]
	[ProgId(TranslateTree.PROGID)]
	public class TranslateTree : ISchematicAlgorithm, ITranslateTree
	{
		// private member data
		public const string GUID = "A675D260-6AF0-438d-80AB-630B3F956D05";
		private const string PROGID = "ApplicativeAlgorithms.TranslateTree";
		// property names (for the algorithm property set)
		private const string TranslationFactorXName = "Translation Factor X";
		private const string TranslationFactorYName = "Translation Factor Y";
		private string m_algoLabel = "Translate Tree C#";
		private bool m_available;
		private bool m_overridable;
		private bool m_useRootNode;
		private bool m_useEndNode;
		private double m_paramX;
		private double m_paramY;
		private ISchematicDiagramClassName m_schematicDiagramClassName;
		public TranslateTree()
		{
			m_paramX = 50.0;
			m_paramY = 50.0;
			m_available = true;// In this example, the algorithm is available by default
			m_overridable = true; // user is allowed to edit the parameters
			m_useRootNode = false; // don't need the user to define root nodes
			m_useEndNode = false; // don't need the user to define an end node
			m_schematicDiagramClassName = null;
		}
		~TranslateTree()
		{
			m_schematicDiagramClassName = null;
		}
		#region Component Category Registration
		[ComRegisterFunction()]
		public static void Reg(string regKey)
		{
			SchematicAlgorithms.Register(regKey);
		}
		[ComUnregisterFunction()]
		public static void Unreg(string regKey)
		{
			SchematicAlgorithms.Unregister(regKey);
		}
		#endregion
		#region Implements ITranslateTree
		public double TranslationFactorX
		{
			get
			{
				return m_paramX;
			}
			set
			{
				m_paramX = value;
			}
		}
		public double TranslationFactorY
		{
			get
			{
				return m_paramY;
			}
			set
			{
				m_paramY = value;
			}
		}
		#endregion
		///////////////////////////////////////////////////////////////////////////////////////
		//
		// ISchematicAlgorithm interface : Defines its properties and methods (mandatory)
		//
		#region Implements ISchematicAlgorithm
		public bool get_Enabled(ISchematicLayer schematicLayer)
		{
			if (schematicLayer == null)
				return false;
			// an algorithm needs the diagram to be in editing mode in order to run
			if (!schematicLayer.IsEditingSchematicDiagram())
				return false;
			IEnumSchematicFeature enumFeatures = schematicLayer.GetSchematicSelectedFeatures(true);
			if (enumFeatures == null)
				return false;
			// Count the selected nodes
			int iCount = 0;
			ISchematicFeature feature;
			enumFeatures.Reset();
			feature = enumFeatures.Next();
			while (feature != null && iCount < 2)
			{
				ISchematicInMemoryFeatureClass inMemoryFeatureClass;
				// just want SchematicFeatureNode
				inMemoryFeatureClass = (ISchematicInMemoryFeatureClass)feature.Class;
				if (inMemoryFeatureClass.SchematicElementClass.SchematicElementType == esriSchematicElementType.esriSchematicNodeType)
					iCount++;
				feature = enumFeatures.Next();
			}
			if (iCount == 1)
				return true; // just want one selected node
			else
				return false;
		}
		public bool Available
		{
			get
			{
				return m_available;
			}
			set
			{
				m_available = value;
			}
		}
		public bool Overridable
		{
			get
			{
				return m_overridable;
			}
			set
			{
				m_overridable = value;
			}
		}
		public ISchematicDiagramClassName SchematicDiagramClassName
		{
			get
			{
				return m_schematicDiagramClassName;
			}
			set
			{
				m_schematicDiagramClassName = value;
			}
		}
		public string Label
		{
			get
			{
				return m_algoLabel;
			}
			set
			{
				m_algoLabel = value;
			}
		}
		public bool UseRootNode
		{
			get
			{
				return m_useRootNode;
			}
		}
		public bool UseEndNode
		{
			get
			{
				return m_useEndNode;
			}
		}
		public IPropertySet PropertySet
		{
			get
			{
				// build the property set
				IPropertySet propSet = new PropertySet();
				if (propSet == null)
					return null;
				propSet.SetProperty(TranslationFactorXName, m_paramX);
				propSet.SetProperty(TranslationFactorYName, m_paramY);
				return propSet;
			}
			set
			{
				IPropertySet pPropertySet = value;
				if (pPropertySet != null)
				{
					try
					{
						m_paramX = (double)pPropertySet.GetProperty(TranslationFactorXName);
						m_paramY = (double)pPropertySet.GetProperty(TranslationFactorYName);
					}
					catch { }
				}
			}
		}
		public string AlgorithmCLSID
		{
			get
			{
				//return "{" + GUID + "}";   Working as well with GUID
				return PROGID;
			}
		}
		// The execute part of the algorithm
		public void Execute(ISchematicLayer schematicLayer, ITrackCancel CancelTracker)
		{
			if (schematicLayer == null)
				return;
			// Before Execute part
			ISchematicDiagram schematicDiagram;
			schematicDiagram = schematicLayer.SchematicDiagram;
			if (schematicDiagram == null)
				return;
			// get the diagram spatial reference for geometry transformation
			IGeoDataset geoDataset = (IGeoDataset)schematicDiagram;
			if (geoDataset == null)
				return;
			ISpatialReference spatialReference = geoDataset.SpatialReference;
			ISchematicDiagramClass diagramClass;
			diagramClass = schematicDiagram.SchematicDiagramClass;
			if (diagramClass == null)
				return;
			ISchematicDataset schemDataset;
			schemDataset = diagramClass.SchematicDataset;
			if (schemDataset == null)
				return;
			ISchematicAlgorithmEventsTrigger algorithmEventsTrigger;
			algorithmEventsTrigger = (ISchematicAlgorithmEventsTrigger)schemDataset;
			if (algorithmEventsTrigger == null)
				return;
			ESRI.ArcGIS.Carto.ILayer layer = (ESRI.ArcGIS.Carto.ILayer)schematicLayer;
			ISchematicAlgorithm algorithm = (ISchematicAlgorithm)this;
			bool canExecute = true;
			algorithmEventsTrigger.FireBeforeExecuteAlgorithm(layer, algorithm, ref canExecute);
			if (!canExecute)
				return; // cannot execute
			// Get the selected Features
			IEnumSchematicFeature enumFeatures = schematicLayer.GetSchematicSelectedFeatures(true);
			if (enumFeatures == null)
				return;
			// Count the selected nodes
			ISchematicInMemoryFeatureClass inMemoryFeatureClass;
			ISchematicFeature selectedFeature = null;
			int iCount = 0;
			ISchematicFeature schemFeature;
			enumFeatures.Reset();
			schemFeature = enumFeatures.Next();
			while (schemFeature  != null && iCount < 2)
			{
				// just want SchematicFeatureNode
				inMemoryFeatureClass = (ISchematicInMemoryFeatureClass)schemFeature.Class;
				if (inMemoryFeatureClass.SchematicElementClass.SchematicElementType == esriSchematicElementType.esriSchematicNodeType)
				{
					selectedFeature = schemFeature;
					iCount++;
				}
				schemFeature = enumFeatures.Next();
			}
			if (iCount != 1 || selectedFeature == null)
				return; // must be only one
			// Create a new SchematicAnalystFindConnected algorithm
			ISchematicAnalystFindConnected analystFindConnected = null;
			analystFindConnected = (ISchematicAnalystFindConnected)new SchematicAnalystFindConnected();
			if (analystFindConnected == null)
				return;
			// Modifying parameters value for this SchematicAnalystFindConnected algorithm so that when it is launched the trace result appears   a selection set{
			analystFindConnected.SelectLink = true;
			analystFindConnected.SelectNode = true;
			analystFindConnected.UseFlow = false;
			//pAnalystFindConnected.FlowDirection = 1;
			// Execute the algorithm
			analystFindConnected.Execute(schematicLayer, CancelTracker);
			// Retrieving the trace result (if any)
			IEnumSchematicFeature resultFeatures;
			resultFeatures = analystFindConnected.TraceResult;
			if (resultFeatures == null || resultFeatures.Count < 1)
				return;
			// Apply the translation to the result
			ISchematicInMemoryDiagram inMemoryDiagram;
			inMemoryDiagram = schematicLayer.SchematicInMemoryDiagram;
			// Translating each traced elements according to the TranslationFactorX and TranslationFactorY parameters current values
			ISchematicInMemoryFeature inMemoryFeature;
			resultFeatures.Reset();
			while ((inMemoryFeature = (ISchematicInMemoryFeature)resultFeatures.Next()) != null)
			{
				IGeometry geometry;
				ITransform2D transform;
				esriSchematicElementType elemType;
				inMemoryFeatureClass = (ISchematicInMemoryFeatureClass)inMemoryFeature.Class;
				elemType = inMemoryFeatureClass.SchematicElementClass.SchematicElementType;
				if (elemType == esriSchematicElementType.esriSchematicLinkType || elemType == esriSchematicElementType.esriSchematicNodeType)
				{
					// get a copy of the feature geometry
					// then process the cloned geometry rather than the feature geometry directly
					// Thus the modifications are stored in the heap of the current operation
					// meaning it can be undone then redo (undo/redo)
					geometry = inMemoryFeature.ShapeCopy;
					// Convert the geometry into the SpatialReference of diagram class
					geometry.Project(spatialReference);
					// Move the geometry
					transform = (ITransform2D)geometry;
					if (transform != null)
					{
						transform.Move(m_paramX, m_paramY);
						// Convert the moved geometry into the spatial reference of storage
						// and feed it back to the feature
						IObjectClass table = inMemoryFeature.Class;
						if (table == null)
							continue;
						IGeoDataset featureGeoDataset = (IGeoDataset)table;
						if (featureGeoDataset == null)
							continue;
						ISpatialReference featureSpatialRef = featureGeoDataset.SpatialReference;
						if (featureSpatialRef == null)
							continue;
						IGeometry movedGeometry = (IGeometry)transform;
						movedGeometry.Project(featureSpatialRef);
						inMemoryFeature.Shape = movedGeometry;
					}
				}
			}
			// After Execute part
			algorithmEventsTrigger.FireAfterExecuteAlgorithm(layer, algorithm);
			// update the diagram extent
			schematicLayer.UpdateExtent();
		}
		#endregion
	}
}
[Visual Basic .NET]
TranslateTree.vb
Imports System
Imports System.Collections.Generic
Imports System.Text
Imports System.Runtime.InteropServices
Imports ESRI.ArcGIS.esriSystem
Imports ESRI.ArcGIS.ADF.CATIDs
Imports ESRI.ArcGIS.Schematic
Imports ESRI.ArcGIS.Geodatabase
Imports ESRI.ArcGIS.Geometry
<ClassInterface(ClassInterfaceType.None)> _
<Guid(TranslateTree.GUID)> _
<ProgId(TranslateTree.PROGID)> _
Public Class TranslateTree
	Implements ISchematicAlgorithm
	Implements ITranslateTree
	' private member data
	Public Const GUID As String = "F80339F6-9E87-4a75-AF8E-1B44C76D7D96"
	Public Const PROGID As String = "ApplicativeAlgorithms.TranslateTreeVB"
	' property names (for the algorithm property set)
	Private Const TranslationFactorXName As String = "Translation Factor X"
	Private Const TranslationFactorYName As String = "Translation Factor Y"
	Private m_algoLabel As String = "Translate Tree VBNet"
	Private m_available As Boolean
	Private m_overridable As Boolean
	Private m_useRootNode As Boolean
	Private m_useEndNode As Boolean
	Private m_paramX As Double
	Private m_paramY As Double
	Private m_schematicDiagramClassName As ISchematicDiagramClassName
	Public Sub New()
		m_paramX = 50.0
		m_paramY = 50.0
		m_available = True	' In this example, the algorithm is available by default
		m_overridable = True	 ' user is allowed to edit the parameters
		m_useRootNode = False	' don't need the user to define root nodes
		m_useEndNode = False	 ' don't need the user to define an end node
		m_schematicDiagramClassName = Nothing
	End Sub
	Protected Overrides Sub Finalize()
		m_schematicDiagramClassName = Nothing
	End Sub
#Region "COM Registration Function(s)"
	<ComRegisterFunction()> _
	<ComVisibleAttribute(True)> _
	Public Shared Sub Reg(ByVal sKey As String)
		SchematicAlgorithms.Register(sKey)
	End Sub
	<ComUnregisterFunction()> _
	<ComVisibleAttribute(True)> _
	Public Shared Sub Unreg(ByVal sKey As String)
		SchematicAlgorithms.Unregister(sKey)
	End Sub
#End Region
#Region "Implements ITranslateTree"
	Public Property TranslationFactorX() As Double Implements ITranslateTree.TranslationFactorX
		Get
			Return m_paramX
		End Get
		Set(ByVal value As Double)
			m_paramX = value
		End Set
	End Property
	Public Property TranslationFactorY() As Double Implements ITranslateTree.TranslationFactorY
		Get
			Return m_paramY
		End Get
		Set(ByVal value As Double)
			m_paramY = value
		End Set
	End Property
#End Region
#Region "Implements ISchematicAlgorithm"
	Public ReadOnly Property Enabled(Optional ByVal schematicLayer As ESRI.ArcGIS.Schematic.ISchematicLayer = Nothing) As Boolean Implements ESRI.ArcGIS.Schematic.ISchematicAlgorithm.Enabled
		Get
			Dim enumFeatures As IEnumSchematicFeature
			Dim schemFeature As ISchematicFeature
			Dim iCount As Integer = 0
			If (schematicLayer Is Nothing) Then Return False
			' an algorithm needs the diagram to be in editing mode in order to run
			If (Not schematicLayer.IsEditingSchematicDiagram()) Then Return False
			enumFeatures = schematicLayer.GetSchematicSelectedFeatures(True)
			If (enumFeatures Is Nothing) Then Return False
			' Count the selected nodes
			enumFeatures.Reset()
			schemFeature = enumFeatures.Next()
			While (schemFeature IsNot Nothing And iCount < 2)
				Dim inMemoryFeatureClass As ISchematicInMemoryFeatureClass = Nothing
				inMemoryFeatureClass = TryCast(schemFeature.Class, ISchematicInMemoryFeatureClass)
				If (inMemoryFeatureClass Is Nothing) Then
					schemFeature = enumFeatures.Next()
					Continue While
				End If
				If (inMemoryFeatureClass.SchematicElementClass.SchematicElementType = esriSchematicElementType.esriSchematicNodeType) Then
					iCount += 1
				End If
				schemFeature = enumFeatures.Next()
			End While
			If (iCount = 1) Then
				Return True	'  just want one selected node
			Else
				Return False
			End If
		End Get
	End Property
	Public Property Available() As Boolean Implements ISchematicAlgorithm.Available
		Get
			Return m_available
		End Get
		Set(ByVal value As Boolean)
			m_available = value
		End Set
	End Property
	' enclose the name of the property by brackets since the word is reserved (in VBNet)
	Public Property [Overridable]() As Boolean Implements ISchematicAlgorithm.Overridable
		Get
			Return m_overridable
		End Get
		Set(ByVal value As Boolean)
			m_overridable = value
		End Set
	End Property
	Public Property SchematicDiagramClassName() As ISchematicDiagramClassName Implements ISchematicAlgorithm.SchematicDiagramClassName
		Get
			Return m_schematicDiagramClassName
		End Get
		Set(ByVal value As ISchematicDiagramClassName)
			m_schematicDiagramClassName = value
		End Set
	End Property
	Public Property Label() As String Implements ISchematicAlgorithm.Label
		Get
			Return m_algoLabel
		End Get
		Set(ByVal value As String)
			m_algoLabel = value
		End Set
	End Property
	Public ReadOnly Property UseRootNode() As Boolean Implements ISchematicAlgorithm.UseRootNode
		Get
			Return m_useRootNode
		End Get
	End Property
	Public ReadOnly Property UseEndNode() As Boolean Implements ISchematicAlgorithm.UseEndNode
		Get
			Return m_useEndNode
		End Get
	End Property
	Public Property PropertySet() As IPropertySet Implements ISchematicAlgorithm.PropertySet
		Get
			' build the property set
			Dim builtPropertySet As New ESRI.ArcGIS.esriSystem.PropertySet
			If (builtPropertySet Is Nothing) Then
				Return Nothing
			End If
			builtPropertySet.SetProperty(TranslationFactorXName, m_paramX)
			builtPropertySet.SetProperty(TranslationFactorYName, m_paramY)
			Return builtPropertySet
		End Get
		Set(ByVal value As IPropertySet)
			Dim propSet As IPropertySet = value
			Dim oneParameter As Object
			If (propSet IsNot Nothing) Then
				Try
					oneParameter = propSet.GetProperty(TranslationFactorXName)
					m_paramX = CDbl(oneParameter)
					oneParameter = propSet.GetProperty(TranslationFactorYName)
					m_paramY = CDbl(oneParameter)
				Catch ex As Exception
				End Try
			End If
		End Set
	End Property
	Public ReadOnly Property AlgorithmCLSID() As String Implements ISchematicAlgorithm.AlgorithmCLSID
		Get
			Return "{" & GUID & "}"
		End Get
	End Property
	Public Sub Execute(Optional ByVal schematicLayer As ESRI.ArcGIS.Schematic.ISchematicLayer = Nothing, Optional ByVal cancelTracker As ESRI.ArcGIS.esriSystem.ITrackCancel = Nothing) Implements ESRI.ArcGIS.Schematic.ISchematicAlgorithm.Execute
		If (schematicLayer Is Nothing) Then Return
		'''''''''''''''''''''''''''''''''''''''''''
		' Before Execute part
		Dim schematicDiagram As ISchematicDiagram
		schematicDiagram = schematicLayer.SchematicDiagram
		If (schematicDiagram Is Nothing) Then Return
		' get the diagram spatial reference for geometry transformation
		Dim geoDataset As IGeoDataset = CType(schematicDiagram, IGeoDataset)
		If (geoDataset Is Nothing) Then Return
		Dim spatialReference As ISpatialReference = geoDataset.SpatialReference
		Dim diagramClass As ISchematicDiagramClass
		diagramClass = schematicDiagram.SchematicDiagramClass
		If (diagramClass Is Nothing) Then Return
		Dim schemDataset As ISchematicDataset
		schemDataset = diagramClass.SchematicDataset
		If (schemDataset Is Nothing) Then Return
		Dim algorithmEventsTrigger As ISchematicAlgorithmEventsTrigger
		algorithmEventsTrigger = CType(schemDataset, ISchematicAlgorithmEventsTrigger)
		If (algorithmEventsTrigger Is Nothing) Then Return
		Dim layer As ESRI.ArcGIS.Carto.ILayer = CType(schematicLayer, ESRI.ArcGIS.Carto.ILayer)
		Dim algorithm As ISchematicAlgorithm = CType(Me, ISchematicAlgorithm)
		Dim canExecute As Boolean
		algorithmEventsTrigger.FireBeforeExecuteAlgorithm(layer, algorithm, canExecute)
		If Not canExecute Then Return ' cannot execute
		' Get the selected Features
		Dim enumFeatures As IEnumSchematicFeature = schematicLayer.GetSchematicSelectedFeatures(True)
		If (enumFeatures Is Nothing) Then Return
		' Count the selected nodes
		Dim inMemoryFeatureClass As ISchematicInMemoryFeatureClass
		Dim selectedFeature As ISchematicFeature = Nothing
		Dim iCount As Integer = 0
		Dim schemFeature As ISchematicFeature
		enumFeatures.Reset()
		schemFeature = enumFeatures.Next()
		While (schemFeature IsNot Nothing AndAlso iCount < 2)
			' just want SchematicFeatureNode
			inMemoryFeatureClass = CType(schemFeature.Class, ISchematicInMemoryFeatureClass)
			If (inMemoryFeatureClass.SchematicElementClass.SchematicElementType = esriSchematicElementType.esriSchematicNodeType) Then
				selectedFeature = schemFeature
				iCount += 1
			End If
			schemFeature = enumFeatures.Next()
		End While
		If (iCount <> 1 OrElse selectedFeature Is Nothing) Then Return ' must be only one
		' Create a new SchematicAnalystFindConnected algorithm
		Dim analystFindConnected As ISchematicAnalystFindConnected = Nothing
		analystFindConnected = CType(New SchematicAnalystFindConnected(), ISchematicAnalystFindConnected)
		If (analystFindConnected Is Nothing) Then Return
		' Modifying parameters value for this SchematicAnalystFindConnected algorithm so that when it is launched the trace result appears   a selection set{
		analystFindConnected.SelectLink = True
		analystFindConnected.SelectNode = True
		analystFindConnected.UseFlow = False
		'pAnalystFindConnected.FlowDirection = 1
		' Execute the algorithm
		analystFindConnected.Execute(schematicLayer, cancelTracker)
		' Retrieving the trace result (if any)
		Dim resultFeatures As IEnumSchematicFeature
		resultFeatures = analystFindConnected.TraceResult
		If (resultFeatures Is Nothing OrElse resultFeatures.Count < 1) Then Return
		' Apply the translation to the result
		Dim inMemoryDiagram As ISchematicInMemoryDiagram
		inMemoryDiagram = schematicLayer.SchematicInMemoryDiagram
		' Translating each traced elements according to the TranslationFactorX and TranslationFactorY parameters current values
		Dim inMemoryFeature As ISchematicInMemoryFeature
		resultFeatures.Reset()
		inMemoryFeature = CType(resultFeatures.Next(), ISchematicInMemoryFeature)
		While (inMemoryFeature IsNot Nothing)
			Dim geometry As IGeometry
			Dim transform As ITransform2D
			Dim elemType As esriSchematicElementType
			inMemoryFeatureClass = CType(inMemoryFeature.Class, ISchematicInMemoryFeatureClass)
			elemType = inMemoryFeatureClass.SchematicElementClass.SchematicElementType
			If (elemType = esriSchematicElementType.esriSchematicLinkType OrElse elemType = esriSchematicElementType.esriSchematicNodeType) Then
				' get a copy of the feature geometry
				' then process the cloned geometry rather than the feature geometry directly
				' Thus the modifications are stored in the heap of the current operation
				' meaning it can be undone then redo (undo/redo)
				geometry = inMemoryFeature.ShapeCopy
				' Convert the geometry into the SpatialReference of diagram class
				geometry.Project(spatialReference)
				' Move the geometry
				transform = CType(geometry, ITransform2D)
				If (transform IsNot Nothing) Then
					transform.Move(m_paramX, m_paramY)
					' Convert the moved geometry into the spatial reference of storage
					' and feed it back to the feature
					Dim table As IObjectClass = inMemoryFeature.Class
					If (table Is Nothing) Then Continue While
					Dim featureGeoDataset As IGeoDataset = CType(table, IGeoDataset)
					If (featureGeoDataset Is Nothing) Then Continue While
					Dim featureSpatialRef As ISpatialReference = featureGeoDataset.SpatialReference
					If (featureSpatialRef Is Nothing) Then Continue While
					Dim movedGeometry As IGeometry = CType(transform, IGeometry)
					movedGeometry.Project(featureSpatialRef)
					inMemoryFeature.Shape = movedGeometry
				End If
			End If
			inMemoryFeature = CType(resultFeatures.Next(), ISchematicInMemoryFeature)
		End While
		' After Execute part
		algorithmEventsTrigger.FireAfterExecuteAlgorithm(layer, algorithm)
		' update the diagram extent
		schematicLayer.UpdateExtent()
	End Sub
#End Region
End Class
'End Namespace