/// <summary> /// Determines if a device has any connections on its ports /// </summary> /// <param name="deviceWrapper">Device to check</param> /// <returns>True if any port is connected</returns> public static bool HasAnyConnections(DeviceWrapper deviceWrapper) { // int? inputPortCount = GdbUtils.GetDomainedIntName(deviceWrapper.Feature, ConfigUtil.InputPortsFieldName); // int? outputPortCount = GdbUtils.GetDomainedIntName(deviceWrapper.Feature, ConfigUtil.OutputPortsFieldName); int? inputPortCount = deviceWrapper.inputPorts; int? outputPortCount = deviceWrapper.outputPorts; List<Range> ranges = null; bool isInputClear = true; if (null != inputPortCount && 0 < inputPortCount) { ranges = GetAvailableRanges(deviceWrapper, PortType.Input); isInputClear = AreRangesWholeUnitCount(ranges, (int)inputPortCount); } bool isOutputClear = true; if (null != outputPortCount && 0 < outputPortCount) { ranges = GetAvailableRanges(deviceWrapper, PortType.Output); isOutputClear = AreRangesWholeUnitCount(ranges, (int)outputPortCount); } // If either port type is not clear, there are connections return (!isInputClear || !isOutputClear); }
/// <summary> /// Gets a list of all port numbers from a device that are not connected on the given end /// </summary> /// <param name="device">Device to check</param> /// <param name="portType">Check input or output ports</param> /// <returns>List of int</returns> private static List<int> GetOpenPorts(DeviceWrapper device, PortType portType) { #region Validation if (null == device) { throw new ArgumentNullException("device"); } if (null == device.Feature) { throw new ArgumentException("device.Class cannot be null"); } #endregion List<int> result = new List<int>(); using (ESRI.ArcGIS.ADF.ComReleaser releaser = new ESRI.ArcGIS.ADF.ComReleaser()) { ESRI.ArcGIS.Geodatabase.IFeatureClass deviceFtClass = device.Feature.Class as ESRI.ArcGIS.Geodatabase.IFeatureClass; ESRI.ArcGIS.Geodatabase.IRelationshipClass deviceHasPorts = ConfigUtil.GetPortRelationship(deviceFtClass); if (null != deviceHasPorts) { ESRI.ArcGIS.Geodatabase.ITable portTable = deviceHasPorts.DestinationClass as ESRI.ArcGIS.Geodatabase.ITable; if (null != portTable) { ESRI.ArcGIS.Geodatabase.IQueryFilter filter = new ESRI.ArcGIS.Geodatabase.QueryFilterClass(); releaser.ManageLifetime(filter); filter.WhereClause = string.Format("{0}='{1}' AND {2} IS NULL AND {3}='{4}'", deviceHasPorts.OriginForeignKey, device.Feature.get_Value(deviceFtClass.FindField(deviceHasPorts.OriginPrimaryKey)), ConfigUtil.ConnectedCableFieldName, ConfigUtil.PortTypeFieldName, (PortType.Input == portType ? "1" : "2")); ESRI.ArcGIS.Geodatabase.ICursor portCursor = portTable.Search(filter, true); ESRI.ArcGIS.Geodatabase.IRow portRow = portCursor.NextRow(); int portIdIdx = portTable.FindField(ConfigUtil.PortIdFieldName); while (null != portRow) { result.Add((int)portRow.get_Value(portIdIdx)); ESRI.ArcGIS.ADF.ComReleaser.ReleaseCOMObject(portRow); portRow = portCursor.NextRow(); } ESRI.ArcGIS.ADF.ComReleaser.ReleaseCOMObject(portCursor); } } } return result; }
/// <summary> /// Determines if all the ranges fall between 1 to port count /// </summary> /// <param name="ranges">Ranges to check</param> /// <param name="device">Device to check on</param> /// <param name="portType">Port type</param> /// <returns>True if valid ranges</returns> public static bool AreRangesWithinPortCount(List<Range> ranges, DeviceWrapper device, PortType portType) { bool result = false; // Default to false in case we can't even find the port relationship class #region Validation if (null == ranges) { throw new ArgumentNullException("ranges"); } if (null == device) { throw new ArgumentNullException("device"); } #endregion ESRI.ArcGIS.Geodatabase.IFeatureClass ftClass = device.Feature.Class as ESRI.ArcGIS.Geodatabase.IFeatureClass; if (null != ftClass) { using (ESRI.ArcGIS.ADF.ComReleaser releaser = new ESRI.ArcGIS.ADF.ComReleaser()) { ESRI.ArcGIS.Geodatabase.IRelationshipClass deviceHasPorts = ConfigUtil.GetPortRelationship(ftClass); if (null != deviceHasPorts) { ESRI.ArcGIS.Geodatabase.ITable portTable = deviceHasPorts.DestinationClass as ESRI.ArcGIS.Geodatabase.ITable; int portIdIdx = portTable.FindField(ConfigUtil.PortIdFieldName); if (-1 < portIdIdx) { result = true; // Now that we have the ports, assume we're ok until we find a problem ESRI.ArcGIS.Geodatabase.IQueryFilter filter = new ESRI.ArcGIS.Geodatabase.QueryFilterClass(); releaser.ManageLifetime(filter); filter.SubFields = ConfigUtil.PortIdFieldName; filter.WhereClause = string.Format("{0}='{1}' AND {2}='{3}' AND {4} IS NOT NULL", deviceHasPorts.OriginForeignKey, device.Feature.get_Value(ftClass.FindField(deviceHasPorts.OriginPrimaryKey)), ConfigUtil.PortTypeFieldName, PortType.Input == portType ? 1 : 2, ConfigUtil.PortIdFieldName); ((ESRI.ArcGIS.Geodatabase.IQueryFilterDefinition)filter).PostfixClause = string.Format("ORDER BY {0}", ConfigUtil.PortIdFieldName); ESRI.ArcGIS.Geodatabase.ICursor cursor = portTable.Search(filter, true); releaser.ManageLifetime(cursor); int minPort = int.MinValue; int maxPort = int.MaxValue; ESRI.ArcGIS.Geodatabase.IRow row = cursor.NextRow(); if (null != row) { minPort = (int)row.get_Value(portIdIdx); while (null != row) { maxPort = (int)row.get_Value(portIdIdx); ESRI.ArcGIS.ADF.ComReleaser.ReleaseCOMObject(row); row = cursor.NextRow(); } } foreach (Range r in ranges) { if (r.High > maxPort || minPort > r.Low) { result = false; break; } } } } } } return result; }
/// <summary> /// Finds ranges of ports that are not yet connected /// </summary> /// <param name="device">Device to check for</param> /// <param name="portType">Check input ports or output ports?</param> /// <returns>List of Range</returns> public static List<Range> GetAvailableRanges(DeviceWrapper device, PortType portType) { if (null == device) { throw new ArgumentNullException("device"); } List<int> openPorts = new List<int>(); openPorts.AddRange(GetOpenPorts(device, portType)); openPorts.Sort(); List<Range> openRanges = MergeRanges(openPorts); return openRanges; }
/// <summary> /// Creates given connections between cable and device /// </summary> /// <param name="cable">Cable</param> /// <param name="device">Device</param> /// <param name="units">Units to connect</param> /// <param name="isFromEnd">Is it the cable's from end?</param> /// <param name="portType">Input or Output?</param> /// <param name="isExistingOperation">Flag to control whether we need to wrap this in a new edit operation</param> /// <returns>Success</returns> public bool MakeConnections(FiberCableWrapper cable, DeviceWrapper device, Dictionary<int, int> units, bool isFromEnd, PortType portType, bool isExistingOperation) { bool success = false; bool isOperationOpen = false; #region Validation if (null == cable) { throw new ArgumentNullException("cable"); } if (null == device) { throw new ArgumentNullException("device"); } if (null == units) { throw new ArgumentNullException("units"); } if (ESRI.ArcGIS.Editor.esriEditState.esriStateNotEditing == _editor.EditState) { throw new InvalidOperationException("You must be editing to perform this operation"); } #endregion if (!isExistingOperation) { _editor.StartOperation(); isOperationOpen = true; } try { ESRI.ArcGIS.Geodatabase.IFeatureClass deviceFtClass = device.Feature.Class as ESRI.ArcGIS.Geodatabase.IFeatureClass; ESRI.ArcGIS.Geodatabase.IRelationshipClass deviceHasPorts = ConfigUtil.GetPortRelationship(deviceFtClass); if (null == deviceHasPorts) { throw new Exception("Unable to get port relationship class."); } ESRI.ArcGIS.Geodatabase.ITable portTable = deviceHasPorts.DestinationClass as ESRI.ArcGIS.Geodatabase.ITable; if (null == portTable) { throw new Exception("Invalid destination on port relationship class."); } int portIdIdx = portTable.FindField(ConfigUtil.PortIdFieldName); int fiberNumberIdx = portTable.FindField(ConfigUtil.ConnectedFiberFieldName); int cableIdIdx = portTable.FindField(ConfigUtil.ConnectedCableFieldName); int isFromEndIdx = portTable.FindField(ConfigUtil.ConnectedEndFieldName); string isFromEndValue = isFromEnd ? "T" : "F"; Dictionary<int, int> portsAsKeys = units; if (PortType.Input == portType) { portsAsKeys = new Dictionary<int, int>(); foreach (KeyValuePair<int, int> pair in units) { portsAsKeys[pair.Value] = pair.Key; } } using (ESRI.ArcGIS.ADF.ComReleaser releaser = new ESRI.ArcGIS.ADF.ComReleaser()) { ESRI.ArcGIS.Geodatabase.IQueryFilter filter = new ESRI.ArcGIS.Geodatabase.QueryFilterClass(); releaser.ManageLifetime(filter); string format = "{0}='{1}' AND {2}='{3}'"; filter.WhereClause = string.Format(format, deviceHasPorts.OriginForeignKey, device.Feature.get_Value(deviceFtClass.FindField(deviceHasPorts.OriginPrimaryKey)), ConfigUtil.PortTypeFieldName, (PortType.Input == portType ? "1" : "2")); // Non recylcing cursor since we are doing updates. ESRI.ArcGIS.Geodatabase.ICursor portCursor = portTable.Update(filter, false); releaser.ManageLifetime(portCursor); ESRI.ArcGIS.Geodatabase.IRow portRow = portCursor.NextRow(); while (null != portRow) { object portIdObj = portRow.get_Value(portIdIdx); if (DBNull.Value != portIdObj) { int portId = System.Convert.ToInt32(portIdObj); if (portsAsKeys.ContainsKey(portId)) { portRow.set_Value(cableIdIdx, cable.IPID); portRow.set_Value(isFromEndIdx, isFromEndValue); portRow.set_Value(fiberNumberIdx, portsAsKeys[portId]); portRow.Store(); } } ESRI.ArcGIS.ADF.ComReleaser.ReleaseCOMObject(portRow); portRow = portCursor.NextRow(); } if (isOperationOpen) { _editor.StopOperation("Create Connections"); isOperationOpen = false; } success = true; } } catch(Exception ex) { if (isOperationOpen) { _editor.AbortOperation(); } success = false; throw new Exception("Save operation failed."); } return success; }
/// <summary> /// Determines if all given ranges are available (neither spliced nor connected) /// </summary> /// <param name="units">Units to check</param> /// <param name="cableWrapper">Device to check</param> /// <param name="isFromEnd">Flag of which port type we are checking</param> /// <returns>True if they are all available</returns> public static bool AreRangesAvailable(ICollection<int> units, DeviceWrapper deviceWrapper, PortType portType) { bool result = true; List<int> openPorts = GetOpenPorts(deviceWrapper, portType); foreach(int unit in units) { if (!openPorts.Contains(unit)) { result = false; break; } } return result; }
/// <summary> /// Returns a list of connections between the cable and the device, at the cable's given end, to the device's given port type /// </summary> /// <param name="cable">Cable to check</param> /// <param name="device">Device to check</param> /// <param name="isFromEnd">Digitized end of cable</param> /// <param name="portType">Input or output</param> /// <returns>List of Connection</returns> public List<Connection> GetConnections(FiberCableWrapper cable, DeviceWrapper device, bool isFromEnd, PortType portType) { if (null == cable) { throw new ArgumentNullException("cable"); } if (null == device) { throw new ArgumentNullException("device"); } List<Connection> result = new List<Connection>(); List<int> ports = new List<int>(); List<int> strands = new List<int>(); using (ESRI.ArcGIS.ADF.ComReleaser releaser = new ESRI.ArcGIS.ADF.ComReleaser()) { ESRI.ArcGIS.Geodatabase.IFeatureClass deviceFtClass = device.Feature.Class as ESRI.ArcGIS.Geodatabase.IFeatureClass; ESRI.ArcGIS.Geodatabase.IRelationshipClass deviceHasPorts = ConfigUtil.GetPortRelationship(deviceFtClass); if (null == deviceHasPorts) { throw new Exception("Unable to find port relationship class."); } ESRI.ArcGIS.Geodatabase.ITable portTable = deviceHasPorts.DestinationClass as ESRI.ArcGIS.Geodatabase.ITable; if (null == portTable) { throw new Exception("Invalid destination on port relationship class."); } ESRI.ArcGIS.Geodatabase.IQueryFilter filter = new ESRI.ArcGIS.Geodatabase.QueryFilterClass(); releaser.ManageLifetime(filter); filter.WhereClause = string.Format("{0}='{1}' AND {2}='{3}' AND {4}='{5}' AND {6}='{7}' AND {8} IS NOT NULL AND {9} IS NOT NULL", deviceHasPorts.OriginForeignKey, device.Feature.get_Value(deviceFtClass.FindField(deviceHasPorts.OriginPrimaryKey)), ConfigUtil.ConnectedCableFieldName, cable.IPID, ConfigUtil.PortTypeFieldName, (PortType.Input == portType ? "1" : "2"), ConfigUtil.ConnectedEndFieldName, (isFromEnd ? "T" : "F"), ConfigUtil.ConnectedFiberFieldName, ConfigUtil.PortIdFieldName); // ORDER BY does not work outside of SDE. // Removing for now, should not be important. string orderFormat = "ORDER BY {0}"; if (PortType.Input == portType) { // ((ESRI.ArcGIS.Geodatabase.IQueryFilterDefinition2)filter).PostfixClause = string.Format(orderFormat, ConfigUtil.ConnectedFiberFieldName); } else { // ((ESRI.ArcGIS.Geodatabase.IQueryFilterDefinition2)filter).PostfixClause = string.Format(orderFormat, ConfigUtil.PortIdFieldName); } ESRI.ArcGIS.Geodatabase.ICursor portCursor = portTable.Search(filter, true); ESRI.ArcGIS.Geodatabase.IRow portRow = portCursor.NextRow(); int portIdIdx = portTable.FindField(ConfigUtil.PortIdFieldName); int fiberNumberIdx = portTable.FindField(ConfigUtil.ConnectedFiberFieldName); while (null != portRow) { ports.Add((int)portRow.get_Value(portIdIdx)); strands.Add((int)portRow.get_Value(fiberNumberIdx)); ESRI.ArcGIS.ADF.ComReleaser.ReleaseCOMObject(portRow); portRow = portCursor.NextRow(); } ESRI.ArcGIS.ADF.ComReleaser.ReleaseCOMObject(portCursor); } List<Range> portRanges = SpliceAndConnectionUtils.MergeRanges(ports); List<Range> strandRanges = SpliceAndConnectionUtils.MergeRanges(strands); if (PortType.Input == portType) { result = SpliceAndConnectionUtils.MatchUp(strandRanges, portRanges); } else { result = SpliceAndConnectionUtils.MatchUp(portRanges, strandRanges); } return result; }
//public static FiberDeviceConnectionHelper Instance(HookHelperExt hookHelper, ESRI.ArcGIS.Editor.IEditor editor) //{ // if(_instance != null) // { // return _instance; // } // else // { // _instance = new FiberDeviceConnectionHelper(hookHelper, editor); // return _instance; // } //} /// <summary> /// Returns cables which have an endpoint coincident with the device point /// </summary> /// <param name="deviceWrapper">Device to check</param> /// <returns>List of ConnectableCableWrapper</returns> public List<ConnectableCableWrapper> GetCoincidentCables(DeviceWrapper deviceWrapper) { List<ConnectableCableWrapper> result = new List<ConnectableCableWrapper>(); if (null == deviceWrapper) { throw new ArgumentNullException("deviceWrapper"); } ESRI.ArcGIS.Geometry.IPoint devicePoint = deviceWrapper.Feature.Shape as ESRI.ArcGIS.Geometry.IPoint; ESRI.ArcGIS.Carto.IFeatureLayer cableLayer = _hookHelper.FindFeatureLayer(ConfigUtil.FiberCableFtClassName); ESRI.ArcGIS.Geodatabase.IFeatureClass cableFtClass = cableLayer.FeatureClass; int displayIdx = cableFtClass.FindField(cableLayer.DisplayField); double buffer = _hookHelper.ConvertPixelsToMapUnits(1); List<ESRI.ArcGIS.Geodatabase.IFeature> coincidentCables = GdbUtils.GetLinearsWithCoincidentEndpoints(devicePoint, cableFtClass, buffer); for (int i = 0; i < coincidentCables.Count; i++) { ESRI.ArcGIS.Geodatabase.IFeature ft = coincidentCables[i]; ESRI.ArcGIS.Geometry.IPolyline line = ft.Shape as ESRI.ArcGIS.Geometry.IPolyline; ESRI.ArcGIS.Geometry.IRelationalOperator lineToPoint = line.ToPoint as ESRI.ArcGIS.Geometry.IRelationalOperator; bool isFromEnd = true; if (lineToPoint.Equals(devicePoint)) { isFromEnd = false; } result.Add(new ConnectableCableWrapper(ft, isFromEnd, displayIdx)); } return result; }
/// <summary> /// Deletes given connections between cable to device /// </summary> /// <param name="cable">Cable</param> /// <param name="device">Device</param> /// <param name="units">Units to connect</param> /// <param name="portType">Input or Output?</param> /// <param name="isExistingOperation">Flag to control whether we need to wrap this in an edit operation</param> /// <returns>Success</returns> public bool BreakConnections(FiberCableWrapper cable, DeviceWrapper device, Dictionary<int, int> units, PortType portType, bool isExistingOperation) { bool success = false; bool isOperationOpen = false; #region Validation if (null == cable) { throw new ArgumentNullException("cable"); } if (null == device) { throw new ArgumentNullException("device"); } if (null == units) { throw new ArgumentNullException("units"); } if (ESRI.ArcGIS.Editor.esriEditState.esriStateNotEditing == _editor.EditState) { throw new InvalidOperationException("You must be editing to perform this operation"); } #endregion if (0 < units.Count) { if (!isExistingOperation) { _editor.StartOperation(); isOperationOpen = true; } try { ESRI.ArcGIS.Geodatabase.IFeatureClass deviceFtClass = device.Feature.Class as ESRI.ArcGIS.Geodatabase.IFeatureClass; ESRI.ArcGIS.Geodatabase.IRelationshipClass deviceHasPorts = ConfigUtil.GetPortRelationship(deviceFtClass); if (null == deviceFtClass) { throw new Exception("Unable to find port relationship class."); } ESRI.ArcGIS.Geodatabase.ITable portTable = deviceHasPorts.DestinationClass as ESRI.ArcGIS.Geodatabase.ITable; if (null == portTable) { throw new Exception("Invalid destination on port relationship class."); } using (ESRI.ArcGIS.ADF.ComReleaser releaser = new ESRI.ArcGIS.ADF.ComReleaser()) { ESRI.ArcGIS.Geodatabase.IQueryFilter filter = new ESRI.ArcGIS.Geodatabase.QueryFilterClass(); releaser.ManageLifetime(filter); StringBuilder inList = new StringBuilder(1024); foreach (KeyValuePair<int, int> pair in units) { string appendFormat = "{0},"; if (PortType.Input == portType) { inList.AppendFormat(appendFormat, pair.Key); } else { inList.AppendFormat(appendFormat, pair.Value); } } inList.Remove(inList.Length - 1, 1); string format = "{0}='{1}' AND {2}='{3}' AND {4}='{5}' AND {6} IN ({7})"; filter.WhereClause = string.Format(format, deviceHasPorts.OriginForeignKey, device.Feature.get_Value(deviceFtClass.FindField(deviceHasPorts.OriginPrimaryKey)), ConfigUtil.ConnectedCableFieldName, cable.IPID, ConfigUtil.PortTypeFieldName, (PortType.Input == portType ? "1" : "2"), ConfigUtil.ConnectedFiberFieldName, inList.ToString()); filter.SubFields = string.Format("{0},{1},{2}", ConfigUtil.ConnectedEndFieldName, ConfigUtil.ConnectedFiberFieldName, ConfigUtil.ConnectedCableFieldName); ESRI.ArcGIS.Geodatabase.IRowBuffer buffer = portTable.CreateRowBuffer(); releaser.ManageLifetime(buffer); // We want to set them to null, so we can just send the empty buffer portTable.UpdateSearchedRows(filter, buffer); if (isOperationOpen) { _editor.StopOperation("Break Connections"); isOperationOpen = false; } success = true; } } catch { if (isOperationOpen) { _editor.AbortOperation(); } success = false; } } return success; }
private FiberCableWrapper GetConnectedFiber(DeviceWrapper device, int portId, PortType portType, out int fiberNumber) { FiberCableWrapper result = null; fiberNumber = -1; ESRI.ArcGIS.Geodatabase.IFeatureClass deviceFtClass = (ESRI.ArcGIS.Geodatabase.IFeatureClass)device.Feature.Class; ESRI.ArcGIS.Geodatabase.IRelationshipClass deviceHasPorts = ConfigUtil.GetPortRelationship(deviceFtClass); if (null == deviceHasPorts) { throw new Exception("Device to port relationship is missing or cannot be opened."); } ESRI.ArcGIS.Geodatabase.ITable portTable = deviceHasPorts.DestinationClass as ESRI.ArcGIS.Geodatabase.ITable; if (null == portTable) { throw new Exception("Port table is missing or cannot be opened."); } using (ESRI.ArcGIS.ADF.ComReleaser releaser = new ESRI.ArcGIS.ADF.ComReleaser()) { ESRI.ArcGIS.Geodatabase.IQueryFilter filter = new ESRI.ArcGIS.Geodatabase.QueryFilterClass(); releaser.ManageLifetime(filter); filter.WhereClause = string.Format("{0}='{1}' AND {2}={3} AND {4}='{5}'", deviceHasPorts.OriginForeignKey, device.Feature.get_Value(deviceFtClass.FindField(deviceHasPorts.OriginPrimaryKey)), ConfigUtil.PortIdFieldName, portId, ConfigUtil.PortTypeFieldName, PortType.Input == portType ? 1 : 2); ESRI.ArcGIS.Geodatabase.ICursor cursor = portTable.Search(filter, false); releaser.ManageLifetime(cursor); ESRI.ArcGIS.Geodatabase.IRow portRow = cursor.NextRow(); if (null != portRow) { //releaser.ManageLifetime(portRow); object cableIdValue = portRow.get_Value(portTable.FindField(ConfigUtil.ConnectedCableFieldName)); if (DBNull.Value != cableIdValue) { ESRI.ArcGIS.Geodatabase.IFeatureClass cableFtClass = _wkspHelper.FindFeatureClass(ConfigUtil.FiberCableFtClassName); filter.WhereClause = string.Format("{0}='{1}'", ConfigUtil.IpidFieldName, cableIdValue); ESRI.ArcGIS.Geodatabase.IFeatureCursor cableCursor = cableFtClass.Search(filter, false); releaser.ManageLifetime(cableCursor); ESRI.ArcGIS.Geodatabase.IFeature cable = cableCursor.NextFeature(); if (null != cable) { result = new FiberCableWrapper(cable); object fiberNumberValue = portRow.get_Value(portTable.FindField(ConfigUtil.ConnectedFiberFieldName)); if (DBNull.Value != fiberNumberValue) { int.TryParse(fiberNumberValue.ToString(), out fiberNumber); } } } } } return result; }
/// <summary> /// Update the dropdowns of features on the UI /// </summary> /// <param name="helper">Helper class</param> private void PopulateDropDowns(FiberDeviceConnectionHelper helper) { // Clear the existing choices cboFrom.Items.Clear(); cboTo.Items.Clear(); lblAvailableFrom.Text = ""; lblAvailableTo.Text = ""; // Get the features and the display index for use when creating the wrapper ESRI.ArcGIS.Carto.IFeatureLayer ftLayer = _hookHelper.FindFeatureLayer(ConfigUtil.FiberCableFtClassName); int displayIdx = ftLayer.FeatureClass.FindField(ftLayer.DisplayField); // Get the selected features List<ESRI.ArcGIS.Geodatabase.IFeature> selectedFts = _hookHelper.GetSelectedFeatures(ftLayer); // Add each of the fiber features to the drop down for (int ftIdx = 0; ftIdx < selectedFts.Count; ftIdx++) { FiberCableWrapper w = new FiberCableWrapper(selectedFts[ftIdx], displayIdx); cboFrom.Items.Add(w); } // Now do that same thing for each of the device feature classes string[] deviceClassNames = ConfigUtil.DeviceFeatureClassNames; for (int deviceClassIdx = 0; deviceClassIdx < deviceClassNames.Length; deviceClassIdx++) { string ftClassName = deviceClassNames[deviceClassIdx]; // Get the features and the display index for use when creating the wrapper ftLayer = _hookHelper.FindFeatureLayer(ftClassName); if (ftLayer != null) // what if layer removed from map { selectedFts = _hookHelper.GetSelectedFeatures(ftLayer); displayIdx = ftLayer.FeatureClass.FindField(ftLayer.DisplayField); for (int ftIdx = 0; ftIdx < selectedFts.Count; ftIdx++) { DeviceWrapper w = new DeviceWrapper(selectedFts[ftIdx], displayIdx); cboFrom.Items.Add(w); } } } // Preselect the first choice if (0 < cboFrom.Items.Count) { cboFrom.SelectedItem = cboFrom.Items[0]; } }