LayerAttributesForm.cs
// Copyright 2011 ESRI // // All rights reserved under the copyright laws of the United States // and applicable international laws, treaties, and conventions. // // You may freely redistribute and use this sample code, with or // without modification, provided you include the original copyright // notice and use restrictions. // // See the use restrictions. // using System; using System.Collections.Generic; using System.ComponentModel; using System.Collections; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using ESRI.ArcGISExplorer; using ESRI.ArcGISExplorer.Application; using ESRI.ArcGISExplorer.Mapping; using ESRI.ArcGISExplorer.Geometry; using ESRI.ArcGISExplorer.Data; namespace LayerAttributesCS { public partial class LayerAttributesForm : Form { private TableBindingAdapter _tableAdapter = null; private MapDisplay _mapDisplay = ESRI.ArcGISExplorer.Application.Application.ActiveMapDisplay; private FeatureLayer _fl = null; private string _idColumnName = string.Empty; /// <summary> /// Initializes a new instance of the LayerAttributesForm class. /// </summary> /// <param name="fl">A FeatureLayer</param> public LayerAttributesForm(FeatureLayer fl) { InitializeComponent(); _fl = fl; _idColumnName = _fl.Table.Columns.ObjectIDColumnName; //********************** //Important code - steps //1. Create a new TableBindingAdapter using the Table associated with the specified feature layer. //2. Call the Fill method to populate the adapter with data from the Table. //3. Set the datasource property on the bindingSource1 component. //4. Bind the bindingSource1 component to the dataGridView1 and bindingNavigator1 objects. _tableAdapter = new TableBindingAdapter(_fl.Table); _tableAdapter.Fill(); bindingSource1.DataSource = _tableAdapter; dataGridView1.DataSource = bindingSource1; bindingNavigator1.BindingSource = bindingSource1; //*********************** this.Text = String.Format("{0} Attributes", _fl.Name); btnZoomTo.ToolTipText = "Zoom to feature"; btnClearGraphicForRow.ToolTipText = "Clear graphic for feature"; btnShowGraphicForRow.ToolTipText = "Show graphic for feature"; btnClearAllGraphicsForTable.ToolTipText = string.Format("Remove all {0} graphics", _fl.Name); } #region "public properties" /// <summary> /// Gets the feature layer for which the attribute data is displayed. /// </summary> /// <value>A FeatureLayer object representing spatial, vector data.</value> public FeatureLayer FeatureLayer { get { return _fl; } } #endregion #region "button implementation" /// <summary> /// Handles the Click event of the btnZoomTo control. Zooms to the geometry stored in the Shape column /// of a particular Row. /// </summary> private void btnZoomTo_Click(object sender, EventArgs e) { string idColName = _fl.Table.Columns.ObjectIDColumnName; int objectID = (int)dataGridView1.CurrentRow.Cells[idColName].Value; Row row = _fl.Table.GetRow(objectID); if (row != null) { Geometry geom = row.Geometry; if ((geom != null) && (geom.IsEmpty == false)) { //Zoom if there is a valid geometry that is not empty. _mapDisplay.ZoomTo(geom); } } } /// <summary> /// Handles the Click event of the btnShowGraphicForRow control. Creates a graphic from the geometry stored /// in the Shape column of a particular Row and adds it to the map. /// </summary> /// <remarks>Note that graphics are temporary - they will not be saved in the Map Document (.nmf) and /// additionally they will be removed when the LayerAttributesForm is closed.</remarks> private void btnShowGraphicForRow_Click(object sender, EventArgs e) { string idColName = _fl.Table.Columns.ObjectIDColumnName; int objectID = (int)dataGridView1.CurrentRow.Cells[idColName].Value; Row row = _fl.Table.GetRow(objectID); //Get the Geometry for the selected Row Geometry geometry = row.Geometry; Symbol sym; //Create a new symbol for the Point, Line and Polygon geometry types. Note that other types are not supported. switch (geometry.GeometryType) { case GeometryType.Point: sym = Symbol.Marker.Flag.Red; break; case GeometryType.Polygon: sym = Symbol.Fill.Outline.Blue; break; case GeometryType.Polyline: sym = Symbol.Line.Solid.Green; break; //currently only create symbols for points, lines and polygons default: sym = null; break; } if (sym != null) { //Create a new graphic Graphic gr = new Graphic(geometry, sym); //"Tag" the graphic so that it can be found later and removed FeatureLayerAndObjectId identifier = new FeatureLayerAndObjectId(); identifier.FeatureLayer = _fl; identifier.ObjectId = objectID; gr.Tag = identifier; //add the graphic to the GraphicsCollection _mapDisplay.Graphics.Add(gr); //update the buttons enabled status if required SetButtonEnabledState(); } } /// <summary> /// Handles the Click event of the btnClearGraphicForRow control. Removes a graphic for a particular Row /// </summary> private void btnClearGraphicForRow_Click(object sender, EventArgs e) { int clickedOID = (int)dataGridView1.CurrentRow.Cells[_idColumnName].Value; Graphic graphicToDelete = null; foreach (Graphic graphic in _mapDisplay.Graphics) { object graphicTag = graphic.Tag; if ((graphicTag != null) && (graphicTag is FeatureLayerAndObjectId)) { FeatureLayerAndObjectId customTag = graphicTag as FeatureLayerAndObjectId; FeatureLayer foundLayer = customTag.FeatureLayer; int foundOID = customTag.ObjectId; if ((foundLayer == _fl) && (foundOID == clickedOID)) { graphicToDelete = graphic; break; } } } //if a graphic was found in the Graphics collection for this Row then remove it if (graphicToDelete != null) { _mapDisplay.Graphics.Remove(graphicToDelete); } //update the buttons enabled status if required SetButtonEnabledState(); } /// <summary> /// Handles the Click event of the btnClearAllGraphicsForTable control. Clears all graphics which /// have been added to the map for this feature layer /// </summary> private void btnClearAllGraphicsForTable_Click(object sender, EventArgs e) { List<Graphic> graphicsToDelete = new List<Graphic>(); foreach (Graphic graphic in _mapDisplay.Graphics) { object graphicTag = graphic.Tag; if ((graphicTag != null) && (graphicTag is FeatureLayerAndObjectId)) { FeatureLayerAndObjectId customTag = graphicTag as FeatureLayerAndObjectId; FeatureLayer foundLayer = customTag.FeatureLayer; if (foundLayer == _fl) { graphicsToDelete.Add(graphic); } } } //Delete any graphics associated with this feature layer foreach (Graphic featureGraphic in graphicsToDelete) { _mapDisplay.Graphics.Remove(featureGraphic); } //update the buttons enabled status if required SetButtonEnabledState(); } #endregion #region "other event handlers" /// <summary> /// Handles the FormClosing event and ensures that all graphics are removed for the /// feature layer when the form is closed. /// </summary> private void AttributesForm_FormClosing(object sender, FormClosingEventArgs e) { btnClearAllGraphicsForTable_Click(null, null); } /// <summary> /// Handles the SelectionChanged event within dataGridView1 control by checking to see if the /// button enabled state should be changed. /// </summary> private void dataGridView1_SelectionChanged(object sender, EventArgs e) { SetButtonEnabledState(); } #endregion #region "private methods" /// <summary> /// Determines whether a graphic has already been added to the Map for the selected Row of data. /// </summary> /// <returns>true if a graphic is found, otherwise false.</returns> private bool IsGraphicShownForRow() { int clickedOID = (int)dataGridView1.CurrentRow.Cells[_idColumnName].Value; bool foundGraphicForRow = false; foreach (Graphic graphic in _mapDisplay.Graphics) { object graphicTag = graphic.Tag; if ((graphicTag != null) && (graphicTag is FeatureLayerAndObjectId)) { FeatureLayerAndObjectId customTag = graphicTag as FeatureLayerAndObjectId; FeatureLayer foundLayer = customTag.FeatureLayer; int foundOID = customTag.ObjectId; if ((foundLayer == _fl) && (foundOID == clickedOID)) { foundGraphicForRow = true; break; } } } return foundGraphicForRow; } /// <summary> /// Determines whether any graphics have been added to the map for this Table /// </summary> /// <returns>true if any graphics have been added to the map for this Table, otherwise false</returns> private bool HasMapGotGraphicsForLayer() { bool foundGraphics = false; foreach (Graphic graphic in _mapDisplay.Graphics) { object graphicTag = graphic.Tag; if ((graphicTag != null) && (graphicTag is FeatureLayerAndObjectId)) { FeatureLayerAndObjectId customTag = graphicTag as FeatureLayerAndObjectId; FeatureLayer foundLayer = customTag.FeatureLayer; if (foundLayer == _fl) { foundGraphics = true; break; } } } return foundGraphics; } /// <summary> /// Sets the enabled state for the custom buttons which have been added to the binding navigator /// </summary> private void SetButtonEnabledState() { DataGridViewSelectedRowCollection selectedRows = dataGridView1.SelectedRows; bool enableAddGraphicBtn = false; bool enableRemoveGraphicBtn = false; bool enableZoomToBtn = false; //only enable the buttons after making necessary checks if (selectedRows != null) { enableZoomToBtn = true; bool graphicExistsForRow = IsGraphicShownForRow(); enableAddGraphicBtn = !graphicExistsForRow; enableRemoveGraphicBtn = graphicExistsForRow; btnShowGraphicForRow.Enabled = enableAddGraphicBtn; btnClearGraphicForRow.Enabled = enableRemoveGraphicBtn; btnZoomTo.Enabled = enableZoomToBtn; } //doesn't matter whether there is a selection btnClearAllGraphicsForTable.Enabled = HasMapGotGraphicsForLayer(); } #endregion } /// <summary> /// Helper class used for tagging graphics, allowing then to be easily identified and removed /// </summary> public class FeatureLayerAndObjectId { public int ObjectId { get; set; } public FeatureLayer FeatureLayer { get; set; } } }