LayerAttributesForm.vb
' 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. ' Imports System.Collections.Generic Imports System.ComponentModel Imports System.Collections Imports System.Data Imports System.Drawing Imports System.Linq Imports System.Text Imports System.Windows.Forms Imports ESRI.ArcGISExplorer Imports ESRI.ArcGISExplorer.Application Imports ESRI.ArcGISExplorer.Mapping Imports ESRI.ArcGISExplorer.Geometry Imports ESRI.ArcGISExplorer.Data Public Partial Class LayerAttributesForm Inherits Form Private _tableAdapter As TableBindingAdapter = Nothing Private _mapDisplay As MapDisplay = ESRI.ArcGISExplorer.Application.Application.ActiveMapDisplay Private _fl As FeatureLayer = Nothing Private _idColumnName As String = String.Empty ' <summary> ' Initializes a new instance of the LayerAttributesForm class. ' </summary> ' <param name="fl">A FeatureLayer</param> Public Sub New(ByVal fl As FeatureLayer) 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 '*********************** Me.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) End Sub #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 ReadOnly Property FeatureLayer() As FeatureLayer Get Return _fl End Get End Property #End Region #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 Sub btnZoomTo_Click(ByVal sender As Object, ByVal e As EventArgs) Dim idColName As String = _fl.Table.Columns.ObjectIDColumnName Dim objectID As Integer = CInt(dataGridView1.CurrentRow.Cells(idColName).Value) Dim row As Row = _fl.Table.GetRow(objectID) If row IsNot Nothing Then Dim geom As Geometry = row.Geometry If (geom IsNot Nothing) AndAlso (geom.IsEmpty = False) Then 'Zoom if there is a valid geometry that is not empty. _mapDisplay.ZoomTo(geom) End If End If End Sub ' <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 Sub btnShowGraphicForRow_Click(ByVal sender As Object, ByVal e As EventArgs) Dim idColName As String = _fl.Table.Columns.ObjectIDColumnName Dim objectID As Integer = CInt(dataGridView1.CurrentRow.Cells(idColName).Value) Dim row As Row = _fl.Table.GetRow(objectID) 'Get the Geometry for the selected Row Dim geometry As Geometry = row.Geometry Dim sym As Symbol 'Create a new symbol for the Point, Line and Polygon geometry types. Note that other types are not supported. Select Case geometry.GeometryType Case GeometryType.Point sym = Symbol.Marker.Flag.Red Exit Select Case GeometryType.Polygon sym = Symbol.Fill.Outline.Blue Exit Select Case GeometryType.Polyline sym = Symbol.Line.Solid.Green Exit Select Case Else 'currently only create symbols for points, lines and polygons sym = Nothing Exit Select End Select If sym IsNot Nothing Then 'Create a new graphic Dim gr As New Graphic(geometry, sym) '"Tag" the graphic so that it can be found later and removed Dim identifier As New FeatureLayerAndObjectId() identifier.FeatureLayer = _fl identifier.ObjectId = objectID gr.Tag = identifier 'add the grpahic to the GraphicsCollection _mapDisplay.Graphics.Add(gr) 'update the buttons enabled status if required SetButtonEnabledState() End If End Sub ' <summary> ' Handles the Click event of the btnClearGraphicForRow control. Removes a graphic for a particular Row ' </summary> Private Sub btnClearGraphicForRow_Click(ByVal sender As Object, ByVal e As EventArgs) Dim clickedOID As Integer = CInt(dataGridView1.CurrentRow.Cells(_idColumnName).Value) Dim graphicToDelete As Graphic = Nothing For Each graphic As Graphic In _mapDisplay.Graphics Dim graphicTag As Object = graphic.Tag If Not graphicTag Is Nothing AndAlso TypeOf graphicTag Is FeatureLayerAndObjectId Then Dim customTag As FeatureLayerAndObjectId = DirectCast(graphicTag, FeatureLayerAndObjectId) Dim foundLayer As FeatureLayer = customTag.FeatureLayer Dim foundOID As Integer = customTag.ObjectId If (foundLayer Is _fl) AndAlso (foundOID = clickedOID) Then graphicToDelete = graphic Exit For End If End If Next 'if a graphic was found in the Grpahics collection for this Row then remove it If graphicToDelete IsNot Nothing Then _mapDisplay.Graphics.Remove(graphicToDelete) End If 'update the buttons enabled status if required SetButtonEnabledState() End Sub ' <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 Sub btnClearAllGraphicsForTable_Click(ByVal sender As Object, ByVal e As EventArgs) Dim graphicsToDelete As New List(Of Graphic)() For Each graphic As Graphic In _mapDisplay.Graphics Dim graphicTag As Object = graphic.Tag If Not graphicTag Is Nothing AndAlso TypeOf graphicTag Is FeatureLayerAndObjectId Then Dim customTag As FeatureLayerAndObjectId = DirectCast(graphicTag, FeatureLayerAndObjectId) Dim foundLayer As FeatureLayer = customTag.FeatureLayer If (foundLayer Is _fl) Then graphicsToDelete.Add(graphic) End If End If Next 'Delete any graphics associated with this feature layer For Each featureGraphic As Graphic In graphicsToDelete _mapDisplay.Graphics.Remove(featureGraphic) Next 'update the buttons enabled status if required SetButtonEnabledState() End Sub #End Region #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 Sub AttributesForm_FormClosing(ByVal sender As Object, ByVal e As FormClosingEventArgs) btnClearAllGraphicsForTable_Click(Nothing, Nothing) End Sub ' <summary> ' Handles the SelectionChanged event within dataGridView1 control by checking to see if the ' button enabled state should be changed. ' </summary> Private Sub dataGridView1_SelectionChanged(ByVal sender As Object, ByVal e As EventArgs) SetButtonEnabledState() End Sub #End Region #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 Function IsGraphicShownForRow() As Boolean Dim clickedOID As Integer = CInt(dataGridView1.CurrentRow.Cells(_idColumnName).Value) Dim foundGraphicForRow As Boolean = False For Each graphic As Graphic In _mapDisplay.Graphics Dim graphicTag As Object = graphic.Tag If Not graphicTag Is Nothing AndAlso TypeOf graphicTag Is FeatureLayerAndObjectId Then Dim customTag As FeatureLayerAndObjectId = DirectCast(graphicTag, FeatureLayerAndObjectId) Dim foundLayer As FeatureLayer = customTag.FeatureLayer Dim foundOID As Integer = customTag.ObjectId If (foundLayer Is _fl) AndAlso (foundOID = clickedOID) Then foundGraphicForRow = True Exit For End If End If Next Return foundGraphicForRow End Function ' <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, otehrwise false</returns> Private Function HasMapGotGraphicsForTable() As Boolean Dim foundGraphics As Boolean = False For Each graphic As Graphic In _mapDisplay.Graphics Dim graphicTag As Object = graphic.Tag If Not graphicTag Is Nothing AndAlso TypeOf graphicTag Is FeatureLayerAndObjectId Then Dim customTag As FeatureLayerAndObjectId = DirectCast(graphicTag, FeatureLayerAndObjectId) Dim foundLayer As FeatureLayer = customTag.FeatureLayer If (foundLayer Is _fl) Then foundGraphics = True Exit For End If End If Next Return foundGraphics End Function ' <summary> ' Sets the enabled state for the custom buttons which have been added to the binding navigator ' </summary> Private Sub SetButtonEnabledState() Dim selectedRows As DataGridViewSelectedRowCollection = dataGridView1.SelectedRows Dim enableAddGraphicBtn As Boolean = False Dim enableRemoveGraphicBtn As Boolean = False Dim enableZoomToBtn As Boolean = False 'only enable the buttons after making necessary checks If selectedRows IsNot Nothing Then enableZoomToBtn = True Dim graphicExistsForRow As Boolean = IsGraphicShownForRow() enableAddGraphicBtn = Not graphicExistsForRow enableRemoveGraphicBtn = graphicExistsForRow btnShowGraphicForRow.Enabled = enableAddGraphicBtn btnClearGraphicForRow.Enabled = enableRemoveGraphicBtn btnZoomTo.Enabled = enableZoomToBtn End If 'doesn't matter whether there is a selection btnClearAllGraphicsForTable.Enabled = HasMapGotGraphicsForTable() End Sub #End Region End Class ' <summary> 'Helper class used for tagging graphics, allowing then to be easily identified and removed '</summary> Public Class FeatureLayerAndObjectId Private _featureLayer As FeatureLayer Private _ObjectId As Integer Public Property FeatureLayer() As FeatureLayer Get Return _featureLayer End Get Set(ByVal value As FeatureLayer) _featureLayer = value End Set End Property Public Property ObjectId() As Integer Get Return _ObjectId End Get Set(ByVal value As Integer) _ObjectId = value End Set End Property End Class