ArcObjects Library Reference  

GenerateSchematicTemplate

About the Utility wizard for basic schematic datasets configuration Sample

[C#]

GenerateSchematicTemplate.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 at <your ArcGIS install location>/DeveloperKit10.0/userestrictions.txt.
// namespace SchematicCreateBasicSettingsAddIn

using System;
using System.Collections.Generic;
using System.Collections;
using System.Collections.Specialized;
using System.Text;
using System.IO;
using ESRI.ArcGIS.Schematic;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.DataSourcesGDB;
using ESRI.ArcGIS.ArcCatalogUI;
using ESRI.ArcGIS.ArcCatalog;
using ESRI.ArcGIS.Catalog;
using ESRI.ArcGIS.CatalogUI;
using ESRI.ArcGIS.ArcMap;
using ESRI.ArcGIS.ArcMapUI;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.NetworkAnalysis;
using System.Windows.Forms;
using ESRI.ArcGIS.esriSystem;

namespace SchematicCreateBasicSettingsAddIn
{
	public class GenerateSchematicTemplate : ESRI.ArcGIS.Desktop.AddIns.Button
	{
		#region Variables
		public frmDatasetTemplateName formNames;
		ESRI.ArcGIS.Geodatabase.IWorkspace m_pWS;
		String m_sfn;
		ESRI.ArcGIS.Schematic.ISchematicBuilder m_pB;
		ESRI.ArcGIS.Schematic.ISchematicDataset m_pSDS;
		ESRI.ArcGIS.Schematic.ISchematicStandardBuilder m_pSB;
		ESRI.ArcGIS.Schematic.ISchematicDiagramClass m_pSDT;

		ESRI.ArcGIS.Schematic.ISchematicDatasetImport m_pSDI;

		NameEvents templateInfo;
		public frmSelectItemsToReduce formReduce;
		private bool blnCancel;
		public frmAdvanced formAdvanced;
		private string strLayers;
		private string strNodeLayers;
		NameValueCollection m_myCol = new NameValueCollection();
		private IGxObject m_SelectedObject = null;
		#endregion Attributes

		public GenerateSchematicTemplate()
		{

		}

		private IEnumLayer GetLayers()
		{
			//now get the map document to parse out the feature classes
			GxDialog pGxDialog = new GxDialogClass();
			IEnumGxObject pEnumGxObject;
			bool pResult;

			pGxDialog.ObjectFilter = new GxFilterMapsClass();
			pGxDialog.Title = "Select a map document";
			try
			{
				pResult = pGxDialog.DoModalOpen(0, out pEnumGxObject);
				//check to see if the user canceled the dialog
				if (pResult == false) return null;
				IGxObject pGxObject = pEnumGxObject.Next();
				IMapReader pMapReader = new MapReaderClass();
				pMapReader.Open(pGxObject.FullName.ToString());
				IMap pMap = pMapReader.get_Map(0);
				ESRI.ArcGIS.esriSystem.UID pUID = new ESRI.ArcGIS.esriSystem.UIDClass();
				pUID.Value = "{40A9E885-5533-11D0-98BE-00805F7CED21}";  //feature layer

				IEnumLayer pLayers = pMap.get_Layers(pUID, true);
                return pLayers;
			}
			catch
			{
				//error getting layers
				return null;
			}

		}

		private Dictionary<string, IFeatureClass> ProcessFCs(IEnumFeatureClass fcComplexEdge, IEnumFeatureClass fcComplexNode, IEnumFeatureClass fcSimpleEdge, IEnumFeatureClass fcSimpleNode)
		{
			Dictionary<string, IFeatureClass> pDictionary = new Dictionary<string, IFeatureClass>();

			//handle complex edge
			IFeatureClass fc = fcComplexEdge.Next();
			if (fc != null)
			{
				do
				{
					try
					{
						pDictionary.Add(fc.AliasName, fc);
					}
					catch
					{
						//do nothing
					}
					fc = fcComplexEdge.Next();
				} while (fc != null);
			}

			//handle complex node
			fc = fcComplexNode.Next();
			if (fc != null)
			{
				do
				{
					try
					{
						pDictionary.Add(fc.AliasName, fc);
					}
					catch
					{
						//do nothing
					}
					fc = fcComplexNode.Next();
				} while (fc != null);
			}

			//handle simple edge
			fc = fcSimpleEdge.Next();
			if (fc != null)
			{
				do
				{
					try
					{
						pDictionary.Add(fc.AliasName, fc);
					}
					catch
					{
						//do nothing
					}
					fc = fcSimpleEdge.Next();
				} while (fc != null);
			}

			//handle simple node
			fc = fcSimpleNode.Next();
			if (fc != null)
			{
				do
				{
					try
					{
						pDictionary.Add(fc.AliasName, fc);
					}
					catch
					{
						//do nothing
					}
					fc = fcSimpleNode.Next();
				} while (fc != null);
			}
			return pDictionary;
		}

		private string CreateSchLayers(IEnumLayer pLayers)
		{
			if (pLayers == null) return "";
			ILayer pLayer = pLayers.Next();
			IFeatureLayer featureLayer;
			IFeatureClass featureClass;
			string pStrLayerNames = "";
			IDataset pDataset;
			System.Windows.Forms.Cursor.Current = Cursors.WaitCursor;
			System.Windows.Forms.Cursor.Show();

			m_pSDS.DesignMode = true;
			m_pSDI = (ESRI.ArcGIS.Schematic.ISchematicDatasetImport)m_pSDS;

			Dictionary<string, IFeatureClass> myDictionary = new Dictionary<string, IFeatureClass>();
			IGeometricNetwork gn = null;
			do
			{
				featureLayer = (IFeatureLayer)pLayer;
				featureClass = featureLayer.FeatureClass;
				pDataset = (IDataset)featureClass;

				if (featureClass.FeatureType == esriFeatureType.esriFTSimpleJunction || featureClass.FeatureType == esriFeatureType.esriFTSimpleEdge || featureClass.FeatureType == esriFeatureType.esriFTComplexEdge || featureClass.FeatureType == esriFeatureType.esriFTComplexJunction)
				{

					//The FeatureType property of feature classes that implement this interface will be esriFTSimpleJunction, esriDTSimpleEdge, esriFTComplexJunction, or esriFTComplexEdge.
					INetworkClass networkClass = (INetworkClass)featureLayer.FeatureClass;

					if (networkClass.GeometricNetwork != null)
					{
						//we have a network class
						if ((gn == null) || (gn != networkClass.GeometricNetwork))
						{
							//need to process all the classes
							Dictionary<string, IFeatureClass> localDictionary = new Dictionary<string, IFeatureClass>();
							gn = networkClass.GeometricNetwork;
							IEnumFeatureClass fcComplexEdge = networkClass.GeometricNetwork.get_ClassesByType(esriFeatureType.esriFTComplexEdge);
							IEnumFeatureClass fcComplexNode = networkClass.GeometricNetwork.get_ClassesByType(esriFeatureType.esriFTComplexJunction);
							IEnumFeatureClass fcSimpleEdge = networkClass.GeometricNetwork.get_ClassesByType(esriFeatureType.esriFTSimpleEdge);
							IEnumFeatureClass fcSimpleNode = networkClass.GeometricNetwork.get_ClassesByType(esriFeatureType.esriFTSimpleJunction);
							localDictionary = ProcessFCs(fcComplexEdge, fcComplexNode, fcSimpleEdge, fcSimpleNode);
							if (myDictionary.Count == 0)  //just copy it
							{
								myDictionary = localDictionary;
							}
							else //merge
							{
								Dictionary<string, IFeatureClass>.KeyCollection keyColl = localDictionary.Keys;

								foreach (string s in keyColl)
								{
									IFeatureClass fc;
									bool bln = localDictionary.TryGetValue(s, out fc);
									myDictionary.Add(s, fc);
								}
							}
						}
						//Build up the string that will go to the select items to reduce form
						pStrLayerNames += pDataset.Name.ToString();
						pStrLayerNames += ";";

						//Build up the string for just the node feature classes
						if (featureClass.FeatureType == esriFeatureType.esriFTSimpleJunction || featureClass.FeatureType == esriFeatureType.esriFTComplexJunction)
						{
							strNodeLayers += pDataset.Name.ToString();
							strNodeLayers += ";";
						}

						//create the fields collections to be used by the frmAdvanced form
						IFields pFields = featureClass.Fields;
						if (pFields.FieldCount > 0)
						{
							for (int i = 0; i < pFields.FieldCount; i++)
							{
								//don't mess with objectid or shape or GlobalID
								if ((pFields.get_Field(i).Name.ToString() != "OBJECTID") && (pFields.get_Field(i).Name.ToString() != "SHAPE") && (pFields.get_Field(i).Name.ToString() != "GlobalID") && (pFields.get_Field(i).Name.ToString() != featureClass.OIDFieldName.ToString()) && (pFields.get_Field(i).Name.ToString() != featureClass.ShapeFieldName.ToString()))
								{
									m_myCol.Add(pDataset.Name.ToString(), pFields.get_Field(i).Name.ToString());
								}
							}
						}

						//remove the layer from the list of dictionary classes
						if (myDictionary.ContainsKey(featureClass.AliasName))
						{
							myDictionary.Remove(featureClass.AliasName);
						}

						m_pSDI.ImportFeatureLayer(featureLayer, m_pSDT, true, true, true);
					}
				}
				pLayer = pLayers.Next();
			} while (pLayer != null);

			//handle any feature classes that were not in the map
			if (myDictionary.Count > 0)
			{
				Dictionary<string, IFeatureClass>.KeyCollection keyColl = myDictionary.Keys;
				foreach (string s in keyColl)
				{
					IFeatureClass fc;
					bool bln = myDictionary.TryGetValue(s, out fc);
					IObjectClass o = (IObjectClass)fc;
					pDataset = (IDataset)fc;

					pStrLayerNames += pDataset.Name.ToString();
					pStrLayerNames += ";";

					//Build up the string for just the node feature classes
					if (fc.FeatureType == esriFeatureType.esriFTSimpleJunction || featureClass.FeatureType == esriFeatureType.esriFTComplexJunction)
					{
						strNodeLayers += pDataset.Name.ToString();
						strNodeLayers += ";";
					}

					//create the fields collections to be used by the frmAdvanced form
					IFields pFields = fc.Fields;
					if (pFields.FieldCount > 0)
					{
						for (int i = 0; i < pFields.FieldCount; i++)
						{
							//don't mess with objectid or shape or GlobalID
							if ((pFields.get_Field(i).Name.ToString() != "OBJECTID") && (pFields.get_Field(i).Name.ToString() != "SHAPE") && (pFields.get_Field(i).Name.ToString() != "GlobalID") && (pFields.get_Field(i).Name.ToString() != fc.OIDFieldName.ToString()) && (pFields.get_Field(i).Name.ToString() != fc.ShapeFieldName.ToString()))
							{
								m_myCol.Add(pDataset.Name.ToString(), pFields.get_Field(i).Name.ToString());
							}
						}
					}
					if ((fc.FeatureType == esriFeatureType.esriFTComplexJunction) || (fc.FeatureType == esriFeatureType.esriFTSimpleJunction))
					{
						//node
						m_pSDI.ImportObjectClass(o, m_pSDT, true, esriSchematicElementType.esriSchematicNodeType);
					}
					else
					{
						//link
						m_pSDI.ImportObjectClass(o, m_pSDT, true, esriSchematicElementType.esriSchematicLinkType);
					}
				}
			}

			m_pSDS.Save(ESRI.ArcGIS.esriSystem.esriArcGISVersion.esriArcGISVersionCurrent, true);
			m_pSDS.DesignMode = false;
			return pStrLayerNames;
		}

		protected override void OnClick()
		{
			blnCancel = false;
			formNames = new frmDatasetTemplateName();
			formNames.cancelFormEvent += new EventHandler(formNames_cancelFormEvent);
			formNames.nextFormEvent += new EventHandler<NameEvents>(formNames_nextFormEvent);
			m_SelectedObject = ArcCatalog.ThisApplication.SelectedObject;

			if ((m_SelectedObject.Category == "Schematic Dataset")
					|| (m_SelectedObject.Category.ToLower().Contains("database")))
			{
				if (m_SelectedObject.Category.ToLower().Contains("database"))
				{
					//get dataset and template names, then create the objects
					formNames.blnNewDataset = true;
				}
				else
				{
					//dataset, just get template names, then create objects
					formNames.blnNewDataset = false;
				}
				//show the first form of the wizard 
				if (formNames.ShowDialog() == DialogResult.Cancel)
				{
					formNames = null;
					return;
				}
			}
			else
			{
				//we are not on a database or a schematic dataset
				blnCancel = true;
			}

			if (blnCancel == true)
			{
				System.Windows.Forms.MessageBox.Show("The name of the dataset or template already exists.  Please try again with valid names.");
			}

			if (blnCancel != true)  //only true if the user cancels the first form formNames_cancelFormEvent 
			{
				System.Windows.Forms.Cursor.Current = Cursors.WaitCursor;
				IEnumLayer pEnumLayer = GetLayers();
				if (pEnumLayer == null)
				{
					//should only happen if the user clicks cancel on the gxdialog
					blnCancel = true;
				}
				else
				{
					strLayers = CreateSchLayers(pEnumLayer);
                    if (strLayers.Length > 0) //make sure we get something back
                    {
                        //find out if we need to create node reduction rules
                        formReduce = new frmSelectItemsToReduce();
                        formReduce.doneFormEvent += new EventHandler<ReduceEvents>(formReduce_doneFormEvent);
                        formReduce.cancelFormEvent += new EventHandler(formReduce_cancelFormEvent);

                        formReduce.itemList = strNodeLayers;
                        System.Windows.Forms.Cursor.Current = Cursors.Default;
                        formReduce.ShowDialog();
                    }
                    else
                    {
                        //this can happen if the map document didn't have any
                        //layers corresponding to a geometric network
                        blnCancel = true;
                    }
				}
				System.Windows.Forms.Cursor.Current = Cursors.Default;
			}

			if (blnCancel != true)  //could have cancelled on either frmDatasetTemplateName or frmSelectItemsToReduce
			{
				//Advanced Form
				formAdvanced = new frmAdvanced();
				formAdvanced.doneFormEvent += new EventHandler<AdvancedEvents>(formAdvanced_doneFormEvent);
				formAdvanced.strLayers = this.strLayers;
				formAdvanced.strNodeLayers = this.strNodeLayers;
				formAdvanced.m_myCol = this.m_myCol;
				formAdvanced.ShowDialog();
			}

			ArcCatalog.ThisApplication.Refresh(m_sfn);
			try
			{
				ArcCatalog.ThisApplication.Location = m_SelectedObject.FullName.ToString();
			}
			catch { }

			cleanUp();
		}

		void formReduce_cancelFormEvent(object sender, EventArgs e)
		{
			blnCancel = true;
			formReduce.Close();
		}

		void formAdvanced_doneFormEvent(object sender, AdvancedEvents e)
		{
			m_pSDS.DesignMode = true;
			formAdvanced.Cursor = System.Windows.Forms.Cursors.WaitCursor;
			//process the algorithm if there is one
			if (e.AlgorithmName != "")
			{
				ISchematicAlgoSmartTree a = new SchematicAlgoSmartTreeClass();
				if (e.AlgorithmParams.Count > 0)
				{
					Dictionary<string, string>.KeyCollection keys = e.AlgorithmParams.Keys;
					string strValue = "";
					foreach (string s in keys)
					{
						if (s == "Direction")
						{
							e.AlgorithmParams.TryGetValue(s, out strValue);

							if (strValue == "Top to Bottom")
							{
								a.Direction = esriSchematicAlgoDirection.esriSchematicAlgoTopDown;
							}
							else if (strValue == "Bottom to Top")
							{
								a.Direction = esriSchematicAlgoDirection.esriSchematicAlgoBottomUp;
							}
							else if (strValue == "Left to Right")
							{
								a.Direction = esriSchematicAlgoDirection.esriSchematicAlgoLeftRight;
							}
							else
							{
								a.Direction = esriSchematicAlgoDirection.esriSchematicAlgoRightLeft;
							}
						}
					}
					if (e.RootClass != "")
					{
						ISchematicElementClassContainer pECC = (ISchematicElementClassContainer)m_pSDS;
						ISchematicElementClass pEC = pECC.GetSchematicElementClass(e.RootClass);
						ESRI.ArcGIS.esriSystem.UID u = new ESRI.ArcGIS.esriSystem.UID();
						u.Value = "{3AD9D8B8-0A1D-4F32-ABB5-54B848A46F85}";

						ISchematicAttributeConstant pAttrConst = (ISchematicAttributeConstant)pEC.CreateSchematicAttribute("RootFlag", u);
						ISchematicAttributeManagement pAttrMgmt = (ISchematicAttributeManagement)pAttrConst;
						pAttrMgmt.StorageMode = esriSchematicAttributeStorageMode.esriSchematicAttributeFieldStorage;
						pAttrConst.ConstantValue = "-1";
					}
				}

				m_pSDT.SchematicAlgorithm = (ISchematicAlgorithm)a;

			}

			//check to see if we need to add associated fields
			if (e.FieldsToCreate != null)
			{
				if (e.FieldsToCreate.Count > 0)
				{
					ISchematicElementClassContainer pECC = (ISchematicElementClassContainer)m_pSDS;

					//create the associated field attributes
					string[] keys = e.FieldsToCreate.AllKeys;
					foreach (string s in keys)
					{
						//get the feature class
						ISchematicElementClass pEC = pECC.GetSchematicElementClass(s);
						if (pEC != null)
						{
							string strName = "";
							string[] values = e.FieldsToCreate.GetValues(s);
							foreach (string v in values)
							{
								//create the field
								ESRI.ArcGIS.esriSystem.UID u = new ESRI.ArcGIS.esriSystem.UID();
								u.Value = "{7DE3A19D-32D0-41CD-B896-37CA3AFBD88A}";

								IClass pClass = (IClass)pEC;
								//only handle names that don't already exist in the schematic tables
								if (pClass.FindField(v) == -1)
								{
									strName = v.ToString();

									ISchematicAttributeAssociatedField pFieldAttr = (ISchematicAttributeAssociatedField)pEC.CreateSchematicAttribute(strName, u);
									pFieldAttr.AssociatedFieldName = v;
									ISchematicAttributeManagement pAttrMgmt = (ISchematicAttributeManagement)pFieldAttr;
									pAttrMgmt.StorageMode = esriSchematicAttributeStorageMode.esriSchematicAttributeFieldStorage;
								}
							}
						}
					}
				}
			}

			m_pSDS.Save(ESRI.ArcGIS.esriSystem.esriArcGISVersion.esriArcGISVersionCurrent, true);
			m_pSDS.DesignMode = false;
			formAdvanced.Cursor = System.Windows.Forms.Cursors.Default;
			formAdvanced.Close();
		}

		private Boolean CreateTemplate(NameEvents templateInfo)
		{
			//need to get everything first
			IGxDatabase pDatabase = null;
			ISchematicDiagramClassContainer pDiagramClassContainer = null;

			if (m_SelectedObject.Category == "Schematic Dataset")
			{
				pDatabase = (IGxDatabase)m_SelectedObject.Parent;
			}
			else  //on the database already
			{
				pDatabase = (IGxDatabase)m_SelectedObject;
			}
			m_pWS = pDatabase.Workspace;

			ESRI.ArcGIS.Schematic.ISchematicWorkspaceFactory pSWF = new SchematicWorkspaceFactory();
			ESRI.ArcGIS.Schematic.ISchematicWorkspace pSW = pSWF.Open(m_pWS);

			m_pSDS = pSW.get_SchematicDatasetByName(templateInfo.DatasetName);

			//check to see if the template name already exists
			pDiagramClassContainer = (ISchematicDiagramClassContainer)m_pSDS;
			m_pSDT = pDiagramClassContainer.GetSchematicDiagramClass(templateInfo.TemplateName.ToString());
			if (m_pSDT != null) return false;

			//create the schematic template
			m_pSDT = m_pSDS.CreateSchematicDiagramClass(templateInfo.TemplateName);

			if ((templateInfo.AutoCreate == true) || (templateInfo.UseVertices == true))
			{
				m_pB = (ESRI.ArcGIS.Schematic.ISchematicBuilder)m_pSDT;
				m_pSB = (ESRI.ArcGIS.Schematic.ISchematicStandardBuilder)m_pSDT.SchematicBuilder;
				m_pSB.InitializeLinksVertices = templateInfo.UseVertices;
				m_pSB.AutoCreateElementClasses = templateInfo.AutoCreate;
			}
			m_pSDS.Save(ESRI.ArcGIS.esriSystem.esriArcGISVersion.esriArcGISVersion10, false);
			return true;
		}

		private Boolean CreateDataset(NameEvents templateInfo)
		{
			try
			{
				IGxDatabase pDatabase = (IGxDatabase)m_SelectedObject;

				m_pWS = pDatabase.Workspace;

				ESRI.ArcGIS.Schematic.ISchematicWorkspaceFactory pSWF = new SchematicWorkspaceFactory();
				ESRI.ArcGIS.Schematic.ISchematicWorkspace pSW = pSWF.Open(m_pWS);
				//check to see if this dataset name is already used
				m_pSDS = pSW.get_SchematicDatasetByName(templateInfo.DatasetName.ToString());
				if (m_pSDS != null) return false;

				m_pSDS = pSW.CreateSchematicDataset(templateInfo.DatasetName, "");
				return true;
			}
			catch
			{
				//nothing
				return false;
			}
		}

		void formNames_cancelFormEvent(object sender, EventArgs e)
		{
			//user is canceling the wizard
			formNames.Close();
			formNames = null;
			blnCancel = true;
		}

		void formReduce_doneFormEvent(object sender, ReduceEvents e)
		{
			//user click the done button on the reduce form
			ISchematicBuilderRule pIsbr;
			ISchematicBuilderRuleContainer pIsbrc = (ISchematicBuilderRuleContainer)m_pSDT;
			ISchematicBuilderRuleContainerEdit pIsbrce = (ISchematicBuilderRuleContainerEdit)pIsbrc;

			formReduce.Cursor = System.Windows.Forms.Cursors.WaitCursor;
			string[] selectedItems = e.SelectedObjects;
			m_pSDS.DesignMode = true;
			foreach (string s in selectedItems)
			{
				//setup rule properties
				ISchematicNodeReductionRuleByPriority pRule = new SchematicNodeReductionRuleByPriorityClass();
				pRule.NodeDegreeConstraint = true;
				pRule.ReduceNodeDegree0 = true;
				pRule.ReduceNodeDegree2 = true;
				pRule.ReduceNodeDegree1 = false;
				pRule.ReduceNodeDegreeSup3 = false;

				//set the name and class to reduce
				ISchematicNodeReductionRule pNR = (ISchematicNodeReductionRule)pRule;
				pNR.Description = "Remove " + s.ToString();
				pNR.NodeClassName = s.ToString();

				//add it to the template
				pIsbr = pIsbrce.AddSchematicBuilderRule();
				pIsbr.SchematicRule = (ISchematicRule)pRule;
			}

			//save and close
			m_pSDS.Save(ESRI.ArcGIS.esriSystem.esriArcGISVersion.esriArcGISVersion10, false);
			m_pSDS.DesignMode = false;
			formReduce.Cursor = System.Windows.Forms.Cursors.Default;
			formReduce.Close();
		}

		void formNames_nextFormEvent(object sender, NameEvents e)
		{
			Boolean blnCheck = false;
			//check if we need to create a new dataset
			templateInfo = new NameEvents(e.NewDataset, e.DatasetName, e.TemplateName, e.UseVertices);
			formNames.Cursor = System.Windows.Forms.Cursors.WaitCursor;

			if (templateInfo.NewDataset == true)
			{
				blnCheck = CreateDataset(templateInfo);
				if (blnCheck == false)
				{
					//name already exists
					blnCancel = true;
				}
				else
				{
					blnCheck = CreateTemplate(templateInfo);
					if (blnCheck == false)
					{
						//name already exists
						blnCancel = true;
					}
				}
			}
			else //just create a new template
			{
				blnCheck = CreateTemplate(templateInfo);
				if (blnCheck == false)
				{
					//name already exists
					blnCancel = true;
				}
			}
			formNames.Cursor = System.Windows.Forms.Cursors.Default;
			formNames.Close();
		}

		protected override void OnUpdate()
		{
			Enabled = ArcCatalog.Application != null;
			if ((ArcCatalog.ThisApplication.SelectedObject.Category == "File Geodatabase")
					|| (ArcCatalog.ThisApplication.SelectedObject.Category == "Personal Geodatabase")
					|| (ArcCatalog.ThisApplication.SelectedObject.Category == "Schematic Dataset")
					|| (ArcCatalog.ThisApplication.SelectedObject.Category == "Spatial Database Connection"))
			{
				Enabled = true;
			}
			else
			{
				Enabled = false;
			}

		}

		void cleanUp()
		{
			//m_pWSF = null;
			m_pWS = null;
			m_pSDT = null;
			m_pSDS = null;
			m_pSB = null;
			m_pB = null;
			m_SelectedObject = null;
			templateInfo = null;
			m_pSDI = null;
			formNames = null;
			formReduce = null;
			m_sfn = "";
			blnCancel = false;
			strLayers = "";
			strNodeLayers = "";
		}

	}
}


[Visual Basic .NET]

GenerateSchematicTemplate.vb

' 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 at <your ArcGIS install location>/DeveloperKit10.0/userestrictions.txt.
'Namespace SchematicCreateBasicSettingsAddIn

Imports System.Collections.Generic
Imports System.Collections
Imports System.Collections.Specialized
Imports System.Text
Imports System.IO
Imports ESRI.ArcGIS.Schematic
Imports ESRI.ArcGIS.Geodatabase
Imports ESRI.ArcGIS.ArcCatalog
Imports ESRI.ArcGIS.Catalog
Imports ESRI.ArcGIS.CatalogUI
Imports ESRI.ArcGIS.Carto
Imports System.Windows.Forms

Public Class GenerateSchematicTemplate
	Inherits ESRI.ArcGIS.Desktop.AddIns.Button
#Region "Variables"


	Public formNames As frmDatasetTemplateName
	Private m_pWS As ESRI.ArcGIS.Geodatabase.IWorkspace
	Private m_sfn As String
	Private m_pB As ESRI.ArcGIS.Schematic.ISchematicBuilder
	Private m_pSDS As ESRI.ArcGIS.Schematic.ISchematicDataset
	Private m_pSB As ESRI.ArcGIS.Schematic.ISchematicStandardBuilder
	Private m_pSDT As ESRI.ArcGIS.Schematic.ISchematicDiagramClass

	Private m_pSDI As ESRI.ArcGIS.Schematic.ISchematicDatasetImport

	Private templateInfo As NameEvents
	Public formReduce As frmSelectItemsToReduce
	Private blnCancel As Boolean
	Public formAdvanced As frmAdvanced
	Private strLayers As String
	Private strNodeLayers As String
	Private m_myCol As New NameValueCollection()
	Private m_SelectedObject As IGxObject = Nothing

#End Region


	Public Sub New()

	End Sub

	Private Function GetLayers() As IEnumLayer
		'now get the map document to parse out the feature classes
		Dim pGxDialog As GxDialog = New GxDialogClass()
		Dim pEnumGxObject As IEnumGxObject = Nothing
		Dim pResult As Boolean

		pGxDialog.ObjectFilter = New GxFilterMapsClass()
		pGxDialog.Title = "Select a map document"
		Try
			pResult = pGxDialog.DoModalOpen(0, pEnumGxObject)
			'check to see if the user canceled the dialog
			If pResult = False Then
				Return Nothing
			End If
			Dim pGxObject As IGxObject = pEnumGxObject.Next()
			Dim pMapReader As IMapReader = New MapReaderClass()
			pMapReader.Open(pGxObject.FullName.ToString())
			Dim pMap As IMap = pMapReader.Map(0)
			Dim pUID As ESRI.ArcGIS.esriSystem.UID = New ESRI.ArcGIS.esriSystem.UIDClass()
			pUID.Value = "{40A9E885-5533-11D0-98BE-00805F7CED21}"
			'feature layer
			Dim pLayers As IEnumLayer = pMap.Layers(pUID, True)
			Return pLayers
		Catch
			'error getting layers
			Return Nothing
		End Try

	End Function


	Private Function ProcessFCs(ByVal fcComplexEdge As IEnumFeatureClass, ByVal fcComplexNode As IEnumFeatureClass, ByVal fcSimpleEdge As IEnumFeatureClass, ByVal fcSimpleNode As IEnumFeatureClass) As Dictionary(Of String, IFeatureClass)
		Dim pDictionary As New Dictionary(Of String, IFeatureClass)()

		'handle complex edge
		Dim fc As IFeatureClass = fcComplexEdge.Next()
		If fc IsNot Nothing Then
			Do
				Try
					pDictionary.Add(fc.AliasName, fc)
					'do nothing
				Catch
				End Try
				fc = fcComplexEdge.Next()
			Loop While fc IsNot Nothing
		End If

		'handle complex node
		fc = fcComplexNode.Next()
		If fc IsNot Nothing Then
			Do
				Try
					pDictionary.Add(fc.AliasName, fc)
					'do nothing
				Catch
				End Try
				fc = fcComplexNode.Next()
			Loop While fc IsNot Nothing
		End If

		'handle simple edge
		fc = fcSimpleEdge.Next()
		If fc IsNot Nothing Then
			Do
				Try
					pDictionary.Add(fc.AliasName, fc)
					'do nothing
				Catch
				End Try
				fc = fcSimpleEdge.Next()
			Loop While fc IsNot Nothing
		End If

		'handle simple node
		fc = fcSimpleNode.Next()
		If fc IsNot Nothing Then
			Do
				Try
					pDictionary.Add(fc.AliasName, fc)
					'do nothing
				Catch
				End Try
				fc = fcSimpleNode.Next()
			Loop While fc IsNot Nothing
		End If
		Return pDictionary
	End Function

	Private Function CreateSchLayers(ByVal pLayers As IEnumLayer) As String
		If pLayers Is Nothing Then
			Return ""
		End If
		pLayers.Reset()
		Dim pLayer As ILayer = pLayers.Next()
		Dim featureLayer As IFeatureLayer
		Dim featureClass As IFeatureClass
		Dim pStrLayerNames As String = ""
		Dim pDataset As IDataset
		System.Windows.Forms.Cursor.Current = Cursors.WaitCursor
		System.Windows.Forms.Cursor.Show()

		m_pSDS.DesignMode = True
		m_pSDI = DirectCast(m_pSDS, ESRI.ArcGIS.Schematic.ISchematicDatasetImport)

		Dim myDictionary As New Dictionary(Of String, IFeatureClass)()
		Dim gn As IGeometricNetwork = Nothing
		Do
			featureLayer = DirectCast(pLayer, IFeatureLayer)
			featureClass = featureLayer.FeatureClass
			pDataset = DirectCast(featureClass, IDataset)

			If featureClass.FeatureType = esriFeatureType.esriFTSimpleJunction OrElse featureClass.FeatureType = esriFeatureType.esriFTSimpleEdge OrElse featureClass.FeatureType = esriFeatureType.esriFTComplexEdge OrElse featureClass.FeatureType = esriFeatureType.esriFTComplexJunction Then

				'The FeatureType property of feature classes that implement this interface will be esriFTSimpleJunction, esriDTSimpleEdge, esriFTComplexJunction, or esriFTComplexEdge.
				Dim networkClass As INetworkClass = DirectCast(featureLayer.FeatureClass, INetworkClass)

				If networkClass.GeometricNetwork IsNot Nothing Then
					'we have a network class
					If (gn Is Nothing) OrElse (gn IsNot networkClass.GeometricNetwork) Then
						'need to process all the classes
						Dim localDictionary As New Dictionary(Of String, IFeatureClass)()
						gn = networkClass.GeometricNetwork
						Dim fcComplexEdge As IEnumFeatureClass = networkClass.GeometricNetwork.ClassesByType(esriFeatureType.esriFTComplexEdge)
						Dim fcComplexNode As IEnumFeatureClass = networkClass.GeometricNetwork.ClassesByType(esriFeatureType.esriFTComplexJunction)
						Dim fcSimpleEdge As IEnumFeatureClass = networkClass.GeometricNetwork.ClassesByType(esriFeatureType.esriFTSimpleEdge)
						Dim fcSimpleNode As IEnumFeatureClass = networkClass.GeometricNetwork.ClassesByType(esriFeatureType.esriFTSimpleJunction)
						localDictionary = ProcessFCs(fcComplexEdge, fcComplexNode, fcSimpleEdge, fcSimpleNode)
						If myDictionary.Count = 0 Then
							'just copy it
							myDictionary = localDictionary
						Else
							'merge
							Dim keyColl As Dictionary(Of String, IFeatureClass).KeyCollection = localDictionary.Keys

							For Each s As String In keyColl
								Dim fc As IFeatureClass = Nothing
								Dim bln As Boolean = localDictionary.TryGetValue(s, fc)
								myDictionary.Add(s, fc)
							Next
						End If
					End If
					'Build up the string that will go to the select items to reduce form
					pStrLayerNames += pDataset.Name.ToString()
					pStrLayerNames += ";"

					'Build up the string for just the node feature classes
					If featureClass.FeatureType = esriFeatureType.esriFTSimpleJunction Or featureClass.FeatureType = esriFeatureType.esriFTComplexJunction Then
						strNodeLayers += pDataset.Name.ToString()
						strNodeLayers += ";"
					End If

					'create the fields collections to be used by the frmAdvanced form
					Dim pFields As IFields = featureClass.Fields
					If pFields.FieldCount > 0 Then
						For i As Integer = 0 To pFields.FieldCount - 1
							'don't mess with objectid or shape or GlobalID
							Dim name As String = pFields.Field(i).Name.ToString()
							If (name <> "OBJECTID") AndAlso (name <> "SHAPE") AndAlso (name <> "GlobalID") AndAlso (name <> featureClass.OIDFieldName.ToString()) AndAlso (name <> featureClass.ShapeFieldName.ToString()) Then
								m_myCol.Add(pDataset.Name.ToString(), pFields.Field(i).Name.ToString())
							End If
						Next
					End If

					'remove the layer from the list of dictionary classes
					If myDictionary.ContainsKey(featureClass.AliasName) Then
						myDictionary.Remove(featureClass.AliasName)
					End If

					m_pSDI.ImportFeatureLayer(featureLayer, m_pSDT, True, True, True)
				End If
			End If
			pLayer = pLayers.Next()
		Loop While pLayer IsNot Nothing

		'handle any feature classes that were not in the map
		If myDictionary.Count > 0 Then
			Dim keyColl As Dictionary(Of String, IFeatureClass).KeyCollection = myDictionary.Keys
			For Each s As String In keyColl
				Dim fc As IFeatureClass = Nothing
				Dim bln As Boolean = myDictionary.TryGetValue(s, fc)
				Dim o As IObjectClass = DirectCast(fc, IObjectClass)
				pDataset = DirectCast(fc, IDataset)

				pStrLayerNames += pDataset.Name.ToString()
				pStrLayerNames += ";"

				'Build up the string for just the node feature classes
				If featureClass.FeatureType = esriFeatureType.esriFTSimpleJunction Or featureClass.FeatureType = esriFeatureType.esriFTComplexJunction Then
					strNodeLayers += pDataset.Name.ToString()
					strNodeLayers += ";"
				End If

				'create the fields collections to be used by the frmAdvanced form
				Dim pFields As IFields = fc.Fields
				If pFields.FieldCount > 0 Then
					For i As Integer = 0 To pFields.FieldCount - 1
						'don't mess with objectid or shape or GlobalID
						Dim name As String = pFields.Field(i).Name.ToString()
						If (name <> "OBJECTID") AndAlso (name <> "SHAPE") AndAlso (name <> "GlobalID") AndAlso (name <> fc.OIDFieldName.ToString()) AndAlso (name <> fc.ShapeFieldName.ToString()) Then
							m_myCol.Add(pDataset.Name.ToString(), pFields.Field(i).Name.ToString())
						End If
					Next
				End If
				If (fc.FeatureType = esriFeatureType.esriFTComplexJunction) OrElse (fc.FeatureType = esriFeatureType.esriFTSimpleJunction) Then
					'node
					m_pSDI.ImportObjectClass(o, m_pSDT, True, esriSchematicElementType.esriSchematicNodeType)
				Else
					'link
					m_pSDI.ImportObjectClass(o, m_pSDT, True, esriSchematicElementType.esriSchematicLinkType)
				End If
			Next
		End If

		m_pSDS.Save(ESRI.ArcGIS.esriSystem.esriArcGISVersion.esriArcGISVersionCurrent, True)
		m_pSDS.DesignMode = False
		Return pStrLayerNames
	End Function

	Protected Overrides Sub OnClick()
		blnCancel = False
		formNames = New frmDatasetTemplateName()
		AddHandler formNames.cancelFormEvent, AddressOf formNames_cancelFormEvent
		AddHandler formNames.nextFormEvent, AddressOf formNames_nextFormEvent
		m_SelectedObject = ArcCatalog.ThisApplication.SelectedObject
		If (m_SelectedObject.Category = "Schematic Dataset") OrElse (m_SelectedObject.Category.ToLower().Contains("database")) Then
			If m_SelectedObject.Category.ToLower().Contains("database") Then
				'get dataset and template names, then create the objects
				formNames.blnNewDataset = True
			Else
				'dataset, just get template names, then create objects
				formNames.blnNewDataset = False
			End If
			'show the first form of the wizard 
			If formNames.ShowDialog() = DialogResult.Cancel Then
				formNames = Nothing
				Return
			End If
		Else
			'we are not on a database or a schematic dataset
			blnCancel = True
		End If

		If blnCancel = True Then
			System.Windows.Forms.MessageBox.Show("The name of the dataset or template already exists.  Please try again with valid names.")
		End If

		If blnCancel <> True Then
			'only true if the user cancels the first form formNames_cancelFormEvent
			System.Windows.Forms.Cursor.Current = Cursors.WaitCursor
			strLayers = CreateSchLayers(GetLayers())
			If strLayers.Length > 0 Then
				'make sure we get something back
				'find out if we need to create node reduction rules
				formReduce = New frmSelectItemsToReduce()
				AddHandler formReduce.doneFormEvent, AddressOf formReduce_doneFormEvent
				AddHandler formReduce.cancelFormEvent, AddressOf formReduce_cancelFormEvent

				formReduce.itemList = strNodeLayers
				System.Windows.Forms.Cursor.Current = Cursors.Default
				formReduce.ShowDialog()
            Else
                'this can happen if the map document didn't have any
                'layers corresponding to a geometric network
                blnCancel = True
            End If
			System.Windows.Forms.Cursor.Current = Cursors.Default
		End If

		If blnCancel <> True Then
			'could have cancelled on either frmDatasetTemplateName or frmSelectItemsToReduce
			'Advanced Form
			formAdvanced = New frmAdvanced()
			AddHandler formAdvanced.doneFormEvent, AddressOf formAdvanced_doneFormEvent

			formAdvanced.strLayers = Me.strLayers
			formAdvanced.strNodeLayers = Me.strNodeLayers
			formAdvanced.m_myCol = Me.m_myCol
			formAdvanced.ShowDialog()
		End If

		Try
			ArcCatalog.ThisApplication.Refresh(m_sfn)
			ArcCatalog.ThisApplication.Location = m_SelectedObject.FullName.ToString()
		Catch
		End Try
		cleanUp()
	End Sub


	Private Sub formReduce_cancelFormEvent(ByVal sender As Object, ByVal e As EventArgs)
		blnCancel = True
		formReduce.Close()
	End Sub

	Private Sub formAdvanced_doneFormEvent(ByVal sender As Object, ByVal e As AdvancedEvents)
		m_pSDS.DesignMode = True
		formAdvanced.Cursor = System.Windows.Forms.Cursors.WaitCursor
		'process the algorithm if there is one
		If e.AlgorithmName <> "" Then
			Dim a As ISchematicAlgoSmartTree = New SchematicAlgoSmartTreeClass()
			If e.AlgorithmParams.Count > 0 Then
				Dim keys As Dictionary(Of String, String).KeyCollection = e.AlgorithmParams.Keys
				Dim strValue As String = ""
				For Each s As String In keys
					If s = "Direction" Then
						e.AlgorithmParams.TryGetValue(s, strValue)

						If strValue = "Top to Bottom" Then
							a.Direction = esriSchematicAlgoDirection.esriSchematicAlgoTopDown
						ElseIf strValue = "Bottom to Top" Then
							a.Direction = esriSchematicAlgoDirection.esriSchematicAlgoBottomUp
						ElseIf strValue = "Left to Right" Then
							a.Direction = esriSchematicAlgoDirection.esriSchematicAlgoLeftRight
						Else
							a.Direction = esriSchematicAlgoDirection.esriSchematicAlgoRightLeft
						End If
					End If
				Next
				If e.RootClass <> "" Then
					Dim pECC As ISchematicElementClassContainer = DirectCast(m_pSDS, ISchematicElementClassContainer)
					Dim pEC As ISchematicElementClass = pECC.GetSchematicElementClass(e.RootClass)
					Dim u As New ESRI.ArcGIS.esriSystem.UID()
					u.Value = "{3AD9D8B8-0A1D-4F32-ABB5-54B848A46F85}"

					Dim pAttrConst As ISchematicAttributeConstant = DirectCast(pEC.CreateSchematicAttribute("RootFlag", u), ISchematicAttributeConstant)
					Dim pAttrMgmt As ISchematicAttributeManagement = DirectCast(pAttrConst, ISchematicAttributeManagement)
					pAttrMgmt.StorageMode = esriSchematicAttributeStorageMode.esriSchematicAttributeFieldStorage
					pAttrConst.ConstantValue = "-1"
				End If
			End If


			m_pSDT.SchematicAlgorithm = DirectCast(a, ISchematicAlgorithm)
		End If

		'check to see if we need to add associated fields
		If e.FieldsToCreate IsNot Nothing Then
			If e.FieldsToCreate.Count > 0 Then
				Dim pECC As ISchematicElementClassContainer = DirectCast(m_pSDS, ISchematicElementClassContainer)

				'create the associated field attributes
				Dim keys As String() = e.FieldsToCreate.AllKeys
				For Each s As String In keys
					'get the feature class
					Dim pEC As ISchematicElementClass = pECC.GetSchematicElementClass(s)
					If pEC IsNot Nothing Then
						Dim strName As String = ""
						Dim values As String() = e.FieldsToCreate.GetValues(s)
						For Each v As String In values
							'create the field
							Dim u As New ESRI.ArcGIS.esriSystem.UID()
							u.Value = "{7DE3A19D-32D0-41CD-B896-37CA3AFBD88A}"

							Dim pClass As IClass = DirectCast(pEC, IClass)
							If pClass.FindField(v) <> -1 Then
								'name exists
								strName = "RF" & v.ToString()
							Else
								strName = v.ToString()
							End If
							Dim pFieldAttr As ISchematicAttributeAssociatedField = DirectCast(pEC.CreateSchematicAttribute(strName, u), ISchematicAttributeAssociatedField)
							pFieldAttr.AssociatedFieldName = v
							Dim pAttrMgmt As ISchematicAttributeManagement = DirectCast(pFieldAttr, ISchematicAttributeManagement)

							pAttrMgmt.StorageMode = esriSchematicAttributeStorageMode.esriSchematicAttributeFieldStorage
						Next
					End If
				Next
			End If
		End If

		m_pSDS.Save(ESRI.ArcGIS.esriSystem.esriArcGISVersion.esriArcGISVersionCurrent, True)
		m_pSDS.DesignMode = False
		formAdvanced.Cursor = System.Windows.Forms.Cursors.Default
		formAdvanced.Close()
	End Sub

	Private Function CreateTemplate(ByVal templateInfo As NameEvents) As Boolean
		'need to get everything first
		Dim pDatabase As IGxDatabase = Nothing

		If m_SelectedObject.Category = "Schematic Dataset" Then
			pDatabase = DirectCast(m_SelectedObject.Parent, IGxDatabase)
		Else
			'on the database already
			pDatabase = DirectCast(m_SelectedObject, IGxDatabase)
		End If
		m_pWS = pDatabase.Workspace

		Dim pSWF As ESRI.ArcGIS.Schematic.ISchematicWorkspaceFactory = New SchematicWorkspaceFactory()
		Dim pSW As ESRI.ArcGIS.Schematic.ISchematicWorkspace = pSWF.Open(m_pWS)

		m_pSDS = pSW.SchematicDatasetByName(templateInfo.DatasetName)

		Dim pDCContainer As ISchematicDiagramClassContainer = m_pSDS
		m_pSDT = pDCContainer.GetSchematicDiagramClass(templateInfo.TemplateName.ToString())
		If m_pSDT IsNot Nothing Then
			'name already exists
			Return False
		End If

		'create the schematic template
		m_pSDT = m_pSDS.CreateSchematicDiagramClass(templateInfo.TemplateName)

		If (templateInfo.UseVertices = True) Then
			m_pB = DirectCast(m_pSDT, ESRI.ArcGIS.Schematic.ISchematicBuilder)
			m_pSB = DirectCast(m_pSDT.SchematicBuilder, ESRI.ArcGIS.Schematic.ISchematicStandardBuilder)
			m_pSB.InitializeLinksVertices = templateInfo.UseVertices
		End If
		m_pSDS.Save(ESRI.ArcGIS.esriSystem.esriArcGISVersion.esriArcGISVersion10, False)
		Return True
	End Function

	Private Function CreateDataset(ByVal templateInfo As NameEvents) As Boolean
		Try
			Dim pDatabase As IGxDatabase = DirectCast(m_SelectedObject, IGxDatabase)

			m_pWS = pDatabase.Workspace

			Dim pSWF As ESRI.ArcGIS.Schematic.ISchematicWorkspaceFactory = New SchematicWorkspaceFactory()
			Dim pSW As ESRI.ArcGIS.Schematic.ISchematicWorkspace = pSWF.Open(m_pWS)

			m_pSDS = pSW.SchematicDatasetByName(templateInfo.DatasetName.ToString())
			If m_pSDS IsNot Nothing Then
				'name exists
				Return False
			End If

			m_pSDS = pSW.CreateSchematicDataset(templateInfo.DatasetName, "")
			Return True
		Catch		'ex As Exception
			Return False
		End Try
	End Function

	Private Sub formNames_cancelFormEvent(ByVal sender As Object, ByVal e As EventArgs)
		'user is canceling the wizard
		formNames.Close()
		formNames = Nothing
		blnCancel = True
	End Sub

	Private Sub formReduce_doneFormEvent(ByVal sender As Object, ByVal e As ReduceEvents)
		'user click the done button on the reduce form
		Dim pIsbr As ISchematicBuilderRule
		Dim pIsbrc As ISchematicBuilderRuleContainer = DirectCast(m_pSDT, ISchematicBuilderRuleContainer)
		Dim pIsbrce As ISchematicBuilderRuleContainerEdit = DirectCast(pIsbrc, ISchematicBuilderRuleContainerEdit)

		formReduce.Cursor = System.Windows.Forms.Cursors.WaitCursor
		Dim selectedItems As String() = e.SelectedObjects
		m_pSDS.DesignMode = True
		For Each s As String In selectedItems
			'setup rule properties
			Dim pRule As ISchematicNodeReductionRuleByPriority = New SchematicNodeReductionRuleByPriorityClass()
			pRule.NodeDegreeConstraint = True
			pRule.ReduceNodeDegree0 = True
			pRule.ReduceNodeDegree2 = True
			pRule.ReduceNodeDegree1 = False
			pRule.ReduceNodeDegreeSup3 = False

			'set the name and class to reduce
			Dim pNR As ISchematicNodeReductionRule = DirectCast(pRule, ISchematicNodeReductionRule)
			pNR.Description = "Remove " & s.ToString()
			pNR.NodeClassName = s.ToString()

			'add it to the template
			pIsbr = pIsbrce.AddSchematicBuilderRule()
			pIsbr.SchematicRule = DirectCast(pRule, ISchematicRule)
		Next

		'save and close
		m_pSDS.Save(ESRI.ArcGIS.esriSystem.esriArcGISVersion.esriArcGISVersion10, False)
		m_pSDS.DesignMode = False
		formReduce.Cursor = System.Windows.Forms.Cursors.Default
		formReduce.Close()
	End Sub

	Private Sub formNames_nextFormEvent(ByVal sender As Object, ByVal e As NameEvents)
		Dim blnCheck As Boolean = False
		'check if we need to create a new dataset
		templateInfo = New NameEvents(e.NewDataset, e.DatasetName, e.TemplateName, e.UseVertices)
		formNames.Cursor = System.Windows.Forms.Cursors.WaitCursor

		If templateInfo.NewDataset = True Then
			blnCheck = CreateDataset(templateInfo)
			If blnCheck = False Then
				'name exists
				blnCancel = True
			End If

			blnCheck = CreateTemplate(templateInfo)
			If blnCheck = False Then
				'name exists
				blnCancel = True
			End If
		Else
			'just create a new template
			blnCheck = CreateTemplate(templateInfo)
			If blnCheck = False Then
				'name exists
				blnCancel = True
			End If
		End If
		formNames.Cursor = System.Windows.Forms.Cursors.Default
		formNames.Close()
	End Sub

	Protected Overrides Sub OnUpdate()
		'Enabled = ArcCatalog.Application IsNot Nothing
		Enabled = ArcCatalog.Application IsNot Nothing
		'If (ArcCatalog.ThisApplication.SelectedObject.Category = "File Geodatabase") OrElse (ArcCatalog.ThisApplication.SelectedObject.Category = "Personal Geodatabase") OrElse (ArcCatalog.ThisApplication.SelectedObject.Category = "Schematic Dataset") OrElse (ArcCatalog.ThisApplication.SelectedObject.Category = "Spatial Database Connection") Then
		If (ArcCatalog.ThisApplication.SelectedObject.Category = "File Geodatabase") OrElse (ArcCatalog.ThisApplication.SelectedObject.Category = "Personal Geodatabase") OrElse (ArcCatalog.ThisApplication.SelectedObject.Category = "Schematic Dataset") OrElse (ArcCatalog.ThisApplication.SelectedObject.Category = "Spatial Database Connection") Then
			Enabled = True
		Else
			Enabled = False
		End If

	End Sub

	Private Sub cleanUp()

		m_pWS = Nothing
		m_pSDT = Nothing
		m_pSDS = Nothing
		m_pSB = Nothing
		m_pB = Nothing
		m_SelectedObject = Nothing
		templateInfo = Nothing
		m_pSDI = Nothing
		formNames = Nothing
		formReduce = Nothing
		m_sfn = ""
		blnCancel = False
		strNodeLayers = ""
		strLayers = ""
	End Sub

End Class