LayerAttributesDockWindow.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.Drawing Imports System.Data Imports System.Linq Imports System.Text Imports System.Windows.Forms Imports System.Collections Imports System.Collections.ObjectModel Imports ESRI.ArcGISExplorer Imports ESRI.ArcGISExplorer.Application Imports ESRI.ArcGISExplorer.Mapping Imports ESRI.ArcGISExplorer.Geometry Imports ESRI.ArcGISExplorer.Data Imports ESRI.ArcGISExplorer.Threading Public Partial Class LayerAttributesDockWindow Inherits ESRI.ArcGISExplorer.Application.DockWindow ' <summary> ' The current Map. Note that this variable will be reset in the Application_DocumentOpened ' when a new map is opened. ' </summary> Private _map As Map = Nothing ' <summary> ' A List of all the open LayerAttributesForm forms. ' </summary> Private _openForms As New List(Of LayerAttributesForm)() ' <summary> ' Initializes a new instance of the LayerAttributesDockWindow class. ' </summary> Public Sub New() InitializeComponent() End Sub ' <summary> ' Handles the Load event of the AttributesDockWindow control by settting up events which ' a required for maintaining business logic within the addin. ' </summary> Private Sub AttributesDockWindow_Load(ByVal sender As Object, ByVal e As EventArgs) AddHandler ESRI.ArcGISExplorer.Application.Application.DocumentOpened, New EventHandler(AddressOf Application_DocumentOpened) AddHandler ESRI.ArcGISExplorer.Application.Application.MapItemChanged, New EventHandler(Of MapItemEventArgs)(AddressOf Application_MapItemChanged) 'won't fire first time so call it manually Application_DocumentOpened(Nothing, Nothing) End Sub ' <summary> ' Handles the double-click event of the lstFLayer Listbox by Opening a form displaying ' the attributes of the selected feature layer. ' </summary> Private Sub lstFLayers_DoubleClick(ByVal sender As Object, ByVal e As EventArgs) Try 'Check whether an item has been selected If lstFLayers.SelectedItem IsNot Nothing Then 'Check whether a LayerAttributesForm for this feature layer is already open If IsAttributeWindowOpenForLayer(DirectCast(lstFLayers.SelectedItem, FeatureLayer)) Then 'just give the form focus Dim attForm As LayerAttributesForm = GetOpenAttributesForm(DirectCast(lstFLayers.SelectedItem, FeatureLayer)) If attForm IsNot Nothing Then attForm.Focus() End If Else '*********************************************************************** 'Important Code - Create a new form to display the attribute information '*********************************************************************** ShowAttributesForm() End If End If Catch ex As Exception MessageBox.Show("An error has occurred while showing the form: " & ex.Message, "Error", MessageBoxButtons.OK) End Try End Sub ' <summary> ' Handles the DocumentOpened event by initializing the map variable and setting up the DocWindow display. ' </summary> Private Sub Application_DocumentOpened(ByVal sender As Object, ByVal e As EventArgs) _map = ESRI.ArcGISExplorer.Application.Application.ActiveMapDisplay.Map SetupDisplayFeatureLayerAttributesUsage() 'add the names of all the feature layers in the current map to the listbox Dim layers As ReadOnlyCollection(Of FeatureLayer) = _map.GetMapItems(Of FeatureLayer)() lstFLayers.Items.Clear() For Each fl As FeatureLayer In layers lstFLayers.Items.Add(fl) Next End Sub ' <summary> ' Handles the MapItemChanged event to keep the DocWindow listbox content sychronized ' with the application's table of contents window. ' </summary> ' <param name="sender">The source of the event.</param> ' <param name="e">A MapItemEventArgs object containing the event data which includes notifications ' for when layers are added or removed.</param> Private Sub Application_MapItemChanged(ByVal sender As Object, ByVal e As MapItemEventArgs) 'only check map item changes invloving feature layers If TypeOf e.MapItem Is FeatureLayer Then Dim fLayer As FeatureLayer = DirectCast(e.MapItem, FeatureLayer) If e.Status = MapItemChangeStatus.Added Then 'a new feature layer has been added, so add it to the listbox as well lstFLayers.Items.Add(fLayer) ElseIf e.Status = MapItemChangeStatus.Removing Or e.Status = MapItemChangeStatus.RemovingChild Then 'A feature layer is being removed from the table of contents so close the 'LayerAttributesForm for this feature layer if it is open 'create a temporary list of forms to remove Dim formsToRemoveFromOpenFormsList As New List(Of LayerAttributesForm)() 'add forms to the temporary list For Each attForm As LayerAttributesForm In _openForms Dim fl As FeatureLayer = attForm.FeatureLayer If fLayer Is fl Then formsToRemoveFromOpenFormsList.Add(attForm) End If Next 'now iterate list of forms to close; For Each attform As LayerAttributesForm In formsToRemoveFromOpenFormsList attform.Close() 'this will cause the form_FormClosing event to fire Next 'remove it from the listbox. For Each listboxItem As FeatureLayer In lstFLayers.Items If TypeOf listboxItem Is FeatureLayer Then lstFLayers.Items.Remove(listboxItem) Exit For End If Next End If 'refresh the list box labels if required SetupDisplayFeatureLayerAttributesUsage() End If End Sub ' <summary> ' Handles the FormClosing event by simply removing a reference to the form from the _openForms ArrayList ' </summary> Private Sub form_FormClosing(ByVal sender As Object, ByVal e As FormClosingEventArgs) Dim attributesForm As LayerAttributesForm = DirectCast(sender, LayerAttributesForm) For Each foundForm As LayerAttributesForm In _openForms If attributesForm Is foundForm Then _openForms.Remove(attributesForm) Exit For End If Next End Sub #Region "private methods" ' <summary> ' Creates a new LayerAttributesForm for the specified feature layer, then displays it. ' </summary> Private Sub ShowAttributesForm() Dim form As New LayerAttributesForm(DirectCast(lstFLayers.SelectedItem, FeatureLayer)) AddHandler form.FormClosing, New FormClosingEventHandler(AddressOf form_FormClosing) 'display the form form.Show(ESRI.ArcGISExplorer.Application.Application.Window) 'add form to list of open forms _openForms.Add(form) End Sub ' <summary> ' Sets up the labels and listbox status for the doc window. ' </summary> Private Sub SetupDisplayFeatureLayerAttributesUsage() If _map.GetMapItems(Of FeatureLayer)().Count = 0 Then label1.Text = "No feature layers in map" label2.Text = "" lstFLayers.Enabled = False Else label1.Text = "View the attributes of a feature layer" label2.Text = "in the map by double clicking on the item." lstFLayers.Enabled = True End If End Sub ' <summary> ' Checks to see whether a LayerAttributesForm object already exists for this feature layer. ' </summary> ' <param name="item">A FeatureLayer</param> ' <returns>true if the form is found, otherwise false.</returns> Private Function IsAttributeWindowOpenForLayer(ByVal item As FeatureLayer) As Boolean Dim foundAttributesForm As Boolean = False For Each form As LayerAttributesForm In _openForms Dim fl As FeatureLayer = form.FeatureLayer If item Is fl Then foundAttributesForm = True Exit For End If Next Return foundAttributesForm End Function ' <summary> ' Returns the attributes form for a particular feature layer. ' </summary> ' <param name="item">A FeatureLayer</param> ' <returns>A LayerAttributesForm object which is used to display the attribute data. ' Returns null if a corresponding form is not found.</returns> Private Function GetOpenAttributesForm(ByVal item As FeatureLayer) As LayerAttributesForm Dim openForm As LayerAttributesForm = Nothing For Each form As LayerAttributesForm In _openForms Dim fl As FeatureLayer = form.FeatureLayer If item Is fl Then openForm = form Exit For End If Next Return openForm End Function ' <summary> ' Closes all open attribute forms ' </summary> Private Sub CloseAllOpenAttributeForms() For Each foundForm As LayerAttributesForm In _openForms foundForm.Close() 'then closing event should fire to tidy up resources Exit For Next End Sub #End Region End Class