Common_CustomJavaScript_VBNet\MapDataGridHover.aspx.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 Microsoft.VisualBasic Imports System Public Partial Class MapDataGridHover Inherits System.Web.UI.Page #Region "ASP.NET Page Life Cycle Event Handlers" Protected Sub Page_Load(ByVal sender As Object, ByVal eventArgs As System.EventArgs) ' Get the __EVENTTARGET request parameter. This will specify any controls that are ' the target of the event that triggered the Page request (i.e. postback) Dim requestParameters As System.Collections.Specialized.NameValueCollection = Page.Request.Params Dim controlEvent As String = Nothing Dim controlID As String = requestParameters("__EVENTTARGET") ' Check whether the __EVENTTARGET parameter is null or empty and whether it contains the ' GridView control's ID If (Not String.IsNullOrEmpty(controlID)) AndAlso controlID.Contains(GridView1.ID) Then ' Get any event arguments from the Page request controlEvent = requestParameters("__EVENTARGUMENT") ' If the event arguments contain the string indicating initiation of our ' custom postback event, call the method to zoom to the feature corresponding ' to the clicked row If controlEvent.Contains("CustomSelect$") Then SelectRow(controlEvent, "EventID") End If End If ' Make sure the page is not loading as a result of a postback (i.e. is in initial page load) If (Not IsPostBack) Then ' Create table to hold data to link to graphics Dim dataTable As System.Data.DataTable = New System.Data.DataTable("FireEvents") ' Create and add columns Dim eventIDDataColumn As System.Data.DataColumn = New System.Data.DataColumn("EventID") Dim eventInfoDataColumn As System.Data.DataColumn = New System.Data.DataColumn("EventInfo") dataTable.Columns.Add(eventIDDataColumn) dataTable.Columns.Add(eventInfoDataColumn) ' Create, populate, and add three rows Dim eventDataRow As System.Data.DataRow = dataTable.NewRow() eventDataRow(eventIDDataColumn) = 1 eventDataRow(eventInfoDataColumn) = "value1" dataTable.Rows.Add(eventDataRow) eventDataRow = dataTable.NewRow() eventDataRow(eventIDDataColumn) = 2 eventDataRow(eventInfoDataColumn) = "value2" dataTable.Rows.Add(eventDataRow) eventDataRow = dataTable.NewRow() eventDataRow(eventIDDataColumn) = 3 eventDataRow(eventInfoDataColumn) = "value3" dataTable.Rows.Add(eventDataRow) ' Create a dataset and add the table to it Dim dataSet As System.Data.DataSet = New System.Data.DataSet() dataSet.DataSetName = "FireEventsDataSet" dataSet.Tables.Add(dataTable) ' Set the dataset as the GridView's data source and add a handler for the GridView's RowDataBound event GridView1.DataSource = dataSet AddHandler GridView1.RowDataBound, AddressOf GridView1_RowDataBound ' Add graphics to the map DrawGraphics(dataTable) ' Bind the GridView to its data source and adjust its appearance GridView1.DataBind() GridView1.Visible = True GridView1.BorderWidth = 10 End If End Sub #End Region #Region "WebControl Event Handlers" Private Sub GridView1_RowDataBound(ByVal sender As Object, ByVal gridViewRowEventArgs As System.Web.UI.WebControls.GridViewRowEventArgs) ' Only manipulate data rows If gridViewRowEventArgs.Row.RowType = System.Web.UI.WebControls.DataControlRowType.DataRow Then Dim graphicsMapFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapFunctionality = CType(Map1.GetFunctionality("ADFGraphicsResource"), ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapFunctionality) Dim graphicsTableName As String = TryCast(Session("graphicsTableName"), String) If graphicsMapFunctionality.GraphicsDataSet.Tables.Contains(graphicsTableName) Then Dim datasetName As String = graphicsMapFunctionality.GraphicsDataSet.DataSetName Dim graphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer = TryCast(graphicsMapFunctionality.GraphicsDataSet.Tables(graphicsTableName), ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer) Dim graphicsLayerClientID As String = Map1.GetGraphicsLayerClientID(graphicsLayer) 'string.Format("{0}_{1}", datasetName, graphicsTableName); Dim gridViewRow As System.Web.UI.WebControls.GridViewRow = gridViewRowEventArgs.Row ' The index of the graphic feature is needed to get a reference to the graphic feature client-side. ' The index of a graphic feature is zero-based, and is determined by the order in which it was added ' to its graphic feature group. Here, we can use the gridViewRow's RowIndex, because we know that ' the graphic features were added to the graphics layer in the order of the rows of the data table ' that is bound to the GridView control Dim graphicFeatureIndex As Integer = gridViewRow.RowIndex ' Create a JavaScript string that will (1) set the background color of the current ' row, (2) get the graphicFeatureGroup (i.e. layer) for the GraphicsLayer, (3) get ' the graphicFeature corresponding to the current row index from the ' graphicFeatureGroup, and (4) set the highlight on the graphicFeature Dim jsSetRowAndFeatureHighlight As String = "this.style.backgroundColor='{0}';" & "var graphicFeatureGroup = $find('{1}'); " & "var graphicFeature = graphicFeatureGroup.get({2}); " & "graphicFeature.set_highlight({3});" ' Assign the JavaScript string to the current row's onmouseover event. Specify the ' row's background color as gray and the parameter to graphicFeature.set_highlight ' as true gridViewRow.Attributes.Add("onmouseover", String.Format(jsSetRowAndFeatureHighlight, "gray", graphicsLayerClientID, graphicFeatureIndex, "true")) ' Assign the JavaScript string to the current row's onmouseout event. Specify the ' row's background color as white and the parameter to graphicFeature.set_highlight ' as false gridViewRow.Attributes.Add("onmouseout", String.Format(jsSetRowAndFeatureHighlight, "white", graphicsLayerClientID, graphicFeatureIndex, "false")) ' Construct a JavaScript string that uses Web ADF JavaScript to (1) retrieve the ' graphicFeatureGroup (i.e. layer) corresponding to the graphics data layer, (2) ' get the graphicFeature corresponding to the current row, (3) get the geometry of ' the graphicFeature, (4) get the Page's client-side map object, and (5) zoom to ' the graphicFeature Dim jsZoomToFeature As String = String.Format("var graphicFeatureGroup = $find('{0}'); " & "var graphicFeature = graphicFeatureGroup.get({1}); " & "var geometry = graphicFeature.get_geometry();" & "var map = $find('{2}');" & "map.zoomTo(geometry, .025, true);", graphicsLayerClientID, graphicFeatureIndex, Map1.ClientID) ' Handle click on client gridViewRow.Attributes.Add("onclick", jsZoomToFeature) ' Handle click on server 'string jsDoPostback = ClientScript.GetPostBackEventReference(gridViewRow, "CustomSelect$" + ' gridViewRow.RowIndex); 'gridViewRow.Attributes.Add("onclick", jsDoPostback); End If End If End Sub #End Region #Region "Instance Methods" Private Sub DrawGraphics(ByVal dataTable As System.Data.DataTable) ' Get the map functionality for the graphics resource Dim graphicsMapFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapFunctionality = CType(Map1.GetFunctionality("ADFGraphicsResource"), ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapFunctionality) ' Make sure the graphics have not already been added to the map If (Not Session("graphicsTableName") Is Nothing) OrElse (graphicsMapFunctionality.GraphicsDataSet.Tables.Contains(CStr(Session("graphicsTableName")))) Then Return End If ' Initialize default symbol Dim defaultSymbol As ESRI.ArcGIS.ADF.Web.Display.Symbol.RasterMarkerSymbol = New ESRI.ArcGIS.ADF.Web.Display.Symbol.RasterMarkerSymbol("images/red_fire.gif") defaultSymbol.XOffset = 16 defaultSymbol.YOffset = 16 defaultSymbol.Height = 32 defaultSymbol.Width = 32 defaultSymbol.ImageFormat = ESRI.ArcGIS.ADF.Web.ImageFormat.GIF ' Create default renderer with default symbol Dim defaultRenderer As ESRI.ArcGIS.ADF.Web.Display.Renderer.SimpleRenderer = New ESRI.ArcGIS.ADF.Web.Display.Renderer.SimpleRenderer(defaultSymbol) ' Initialize selected symbol Dim selectedSymbol As ESRI.ArcGIS.ADF.Web.Display.Symbol.RasterMarkerSymbol = New ESRI.ArcGIS.ADF.Web.Display.Symbol.RasterMarkerSymbol("images/yellow_fire.gif") selectedSymbol.XOffset = 16 selectedSymbol.YOffset = 16 selectedSymbol.Height = 32 selectedSymbol.Width = 32 selectedSymbol.ImageFormat = ESRI.ArcGIS.ADF.Web.ImageFormat.GIF ' Create selected renderer with selected symbol Dim selectedRenderer As ESRI.ArcGIS.ADF.Web.Display.Renderer.SimpleRenderer = New ESRI.ArcGIS.ADF.Web.Display.Renderer.SimpleRenderer(selectedSymbol) ' Initialize highlight symbol Dim highlightSymbol As ESRI.ArcGIS.ADF.Web.Display.Symbol.RasterMarkerSymbol = New ESRI.ArcGIS.ADF.Web.Display.Symbol.RasterMarkerSymbol("images/blue_fire.gif") highlightSymbol.XOffset = 16 highlightSymbol.YOffset = 16 highlightSymbol.Height = 32 highlightSymbol.Width = 32 highlightSymbol.ImageFormat = ESRI.ArcGIS.ADF.Web.ImageFormat.GIF ' Create highlight renderer with highlight symbol Dim highlightRenderer As ESRI.ArcGIS.ADF.Web.Display.Renderer.SimpleRenderer = New ESRI.ArcGIS.ADF.Web.Display.Renderer.SimpleRenderer(highlightSymbol) ' Add a geometry column to the events table dataTable.Columns.Add("ADFGeometry", GetType(ESRI.ArcGIS.ADF.Web.Geometry.Geometry)) ' Convert the table to a feature graphics layer Dim eventsFeatureGraphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer = TryCast(ESRI.ArcGIS.ADF.Web.Converter.ToGraphicsLayer(dataTable, defaultRenderer, selectedRenderer, highlightRenderer, False), ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer) ' Assign the layer's name and store it in session eventsFeatureGraphicsLayer.TableName = "MyEvents" Session("graphicsTableName") = eventsFeatureGraphicsLayer.TableName ' Create a random point geometry for each row in the table underlying the grapics layer Dim randomClass As System.Random = New System.Random() For Each dataRow As System.Data.DataRow In eventsFeatureGraphicsLayer.Rows Dim x As Integer = randomClass.Next(-120, -80) Dim y As Integer = randomClass.Next(25, 45) Dim adfPoint As ESRI.ArcGIS.ADF.Web.Geometry.Point = New ESRI.ArcGIS.ADF.Web.Geometry.Point(x, y) adfPoint.SpatialReference = Map1.SpatialReference dataRow(eventsFeatureGraphicsLayer.GeometryColumnName) = adfPoint Next dataRow ' Render the graphics layer on the client without callouts (i.e. maptips) eventsFeatureGraphicsLayer.RenderOnClient = True eventsFeatureGraphicsLayer.EnableCallout = False ' Add the graphics layer to the graphics resource graphicsMapFunctionality.GraphicsDataSet.Tables.Add(eventsFeatureGraphicsLayer) ' Refresh the graphics resource so the new graphics layer appears Map1.RefreshResource(graphicsMapFunctionality.Name) End Sub Private Sub SelectRow(ByVal controlEvent As String, ByVal uniqueIDFieldName As String) ' Parse the control event string Dim controlEventArray As String() = controlEvent.Split("$"c) ' Set the selected index of the GridView to the argument of the control event GridView1.SelectedIndex = System.Int32.Parse(controlEventArray(1)) ' Set the text color of the selected row to red GridView1.SelectedRowStyle.ForeColor = System.Drawing.Color.Red ' Find the column index of the unique ID field Dim uniqueIDFieldIndex As Integer = 0 For Each dataControlField As System.Web.UI.WebControls.DataControlField In GridView1.Columns If dataControlField.HeaderText = uniqueIDFieldName Then Exit For End If uniqueIDFieldIndex += 1 Next dataControlField ' Get the value of the unique ID field from the selected row Dim selectedID As String = GridView1.SelectedRow.Cells(uniqueIDFieldIndex).Text ' Get the map functionality for the graphics resource Dim graphicsMapFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapFunctionality = CType(Map1.GetFunctionality("ADFGraphicsResource"), ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapFunctionality) ' Make sure the target graphics layer is present in the graphics resource Dim graphicsTableName As String = TryCast(Session("graphicsTableName"), String) If graphicsMapFunctionality.GraphicsDataSet.Tables.Contains(graphicsTableName) Then ' Get the target graphics layer Dim graphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer = TryCast(graphicsMapFunctionality.GraphicsDataSet.Tables(graphicsTableName), ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer) ' Unselect all features in the graphics layer For Each dataRow As System.Data.DataRow In graphicsLayer.Rows dataRow("IS_SELECTED") = False Next dataRow ' Use the event ID of the selected row in the GridView to retrieve the corresponding row in the data table ' underlying the linked graphics layer Dim dataRowArray As System.Data.DataRow() = graphicsLayer.Select(String.Format("EventID = '{0}'", selectedID)) ' Assume that only one row was returned from the select operation, making the first row in the array ' the one that corresponds to the graphic we wish to select Dim selectedDataRow As System.Data.DataRow = dataRowArray(0) selectedDataRow("IS_SELECTED") = True ' Get the selected row's geometry Dim adfGeometry As ESRI.ArcGIS.ADF.Web.Geometry.Geometry = graphicsLayer.GeometryFromRow(selectedDataRow) ' Get the envelope of the geoemtry Dim boundingEnvelope As ESRI.ArcGIS.ADF.Web.Geometry.Envelope = New ESRI.ArcGIS.ADF.Web.Geometry.Envelope(Double.MaxValue, Double.MaxValue, Double.MinValue, Double.MinValue) If TypeOf adfGeometry Is ESRI.ArcGIS.ADF.Web.Geometry.Polygon Then BoundingExtent(CType(adfGeometry, ESRI.ArcGIS.ADF.Web.Geometry.Polygon), boundingEnvelope) ' Expand the envelope to include some area around the feature on the map boundingEnvelope.Expand(5) ElseIf TypeOf adfGeometry Is ESRI.ArcGIS.ADF.Web.Geometry.Point Then BoundingExtent(CType(adfGeometry, ESRI.ArcGIS.ADF.Web.Geometry.Point), boundingEnvelope) 'Map1.CenterAt(new ESRI.ArcGIS.ADF.Web.Geometry.Point(boundingEnvelope.XMin, boundingEnvelope.YMin)); ' Expand the bounding envelope so that it is 1/8 of the map width. We do this instead of using ' Envelope.Expand because that method expands by percentage. Since the bounding envelope of a ' poing geometry has a height and width of zero, expanding by any percentage will result in no ' change. Dim mapWidthSixteenth As Double = Map1.GetFullExtent().Width / 16 boundingEnvelope = New ESRI.ArcGIS.ADF.Web.Geometry.Envelope(boundingEnvelope.XMin - mapWidthSixteenth, boundingEnvelope.YMin - mapWidthSixteenth, boundingEnvelope.XMax + mapWidthSixteenth, boundingEnvelope.YMax + mapWidthSixteenth) End If ' Update the map's extent with the envelope Map1.Extent = boundingEnvelope ' Make sure the map has callback results If Map1.CallbackResults.Count > 0 Then ' Register a script block to update the map via the Web ADF processCallbackResult function System.Web.UI.ScriptManager.RegisterClientScriptBlock(Page, Me.GetType(), "updateMap", String.Format("ESRI.ADF.System.processCallbackResult('{0}');", Map1.CallbackResults.ToString().Replace("//", "////")), True) End If End If End Sub ' Retrieves the bounding box of a polygon Private Sub BoundingExtent(ByVal adfPolygon As ESRI.ArcGIS.ADF.Web.Geometry.Polygon, ByVal boundingBox As ESRI.ArcGIS.ADF.Web.Geometry.Envelope) ' Loop through all the rings of the polygon and update the bounding box to account for each vertex Dim i As Integer = 0 Do While i < adfPolygon.Rings.Count Dim adfRing As ESRI.ArcGIS.ADF.Web.Geometry.Ring = adfPolygon.Rings(i) Dim j As Integer = 0 Do While j < adfRing.Points.Count BoundingExtent(adfRing.Points(j), boundingBox) j += 1 Loop i += 1 Loop End Sub Private Sub BoundingExtent(ByVal adfPoint As ESRI.ArcGIS.ADF.Web.Geometry.Point, ByVal boundingBox As ESRI.ArcGIS.ADF.Web.Geometry.Envelope) ' Update the passed-in envelope based on whether the passed-in point falls outside the envelope's bounds If adfPoint.X < boundingBox.XMin Then boundingBox.XMin = adfPoint.X End If If adfPoint.X > boundingBox.XMax Then boundingBox.XMax = adfPoint.X End If If adfPoint.Y < boundingBox.YMin Then boundingBox.YMin = adfPoint.Y End If If adfPoint.Y > boundingBox.YMax Then boundingBox.YMax = adfPoint.Y End If End Sub #End Region End Class