Common_CustomTasks_VBNet\FindNearTask_VBNet\TaskResultsPanel.vb
' Copyright 2010 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 <Assembly: System.Web.UI.WebResource("TaskResultsPanel.js", "text/javascript")> Namespace FindNearTask_VBNet Public Class TaskResultsPanel Inherits ESRI.ArcGIS.ADF.Web.UI.WebControls.FloatingPanel #Region "Instance Variables" Private _resultsGraphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer Private _map As ESRI.ArcGIS.ADF.Web.UI.WebControls.Map #End Region #Region "Public Properties" ' Maximum panel width when the panel is first shown Public Property InitialMaxWidth() As System.Web.UI.WebControls.Unit Get If Me.StateManager.GetProperty("InitialMaxWidth") Is Nothing Then Return New System.Web.UI.WebControls.Unit(-1, System.Web.UI.WebControls.UnitType.Pixel) Else Return CType(Me.StateManager.GetProperty("InitialMaxWidth"), System.Web.UI.WebControls.Unit) End If End Get Set(ByVal value As System.Web.UI.WebControls.Unit) Me.StateManager.SetProperty("InitialMaxWidth", value) End Set End Property ' Maximum panel height when the panel is first shown Public Property InitialMaxHeight() As System.Web.UI.WebControls.Unit Get If Me.StateManager.GetProperty("InitialMaxHeight") Is Nothing Then Return New System.Web.UI.WebControls.Unit(-1, System.Web.UI.WebControls.UnitType.Pixel) Else Return CType(Me.StateManager.GetProperty("InitialMaxHeight"), System.Web.UI.WebControls.Unit) End If End Get Set(ByVal value As System.Web.UI.WebControls.Unit) Me.StateManager.SetProperty("InitialMaxHeight", value) End Set End Property ' Gets the Map control associated with the panel Public ReadOnly Property MapInstance() As ESRI.ArcGIS.ADF.Web.UI.WebControls.Map Get ' Return the map member variable if it already references a Map control If _map IsNot Nothing Then Return _map End If ' If the MapID has been initialized, get the control referenced by that ID If (Not String.IsNullOrEmpty(Me.MapID)) Then _map = TryCast(ESRI.ArcGIS.ADF.Web.UI.WebControls.Utility.FindControl(Me.MapID, Me.Page), ESRI.ArcGIS.ADF.Web.UI.WebControls.Map) End If Return _map End Get End Property ' ID of the Map control associated with the panel Public Property MapID() As String Get Return TryCast(Me.StateManager.GetProperty("ResultsPanelMapID"), String) End Get Set(ByVal value As String) ' Write the ID to state Me.StateManager.SetProperty("ResultsPanelMapID", value) ' Reset the Map member variable so the map is retrieved next time the MapInstance ' property is referenced _map = Nothing End Set End Property ' Gets the GraphicsLayer associated with the panel Public ReadOnly Property GraphicsLayer() As ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer Get If _resultsGraphicsLayer IsNot Nothing Then Return _resultsGraphicsLayer End If _resultsGraphicsLayer = Me.GetGraphicsLayer() Return _resultsGraphicsLayer End Get End Property #End Region #Region "Private Properties" ' Name of the resource containing the associated GraphicsLayer Private Property ResourceName() As String Get Return TryCast(Me.StateManager.GetProperty("ResultsResourceName"), String) End Get Set(ByVal value As String) Me.StateManager.SetProperty("ResultsResourceName", value) End Set End Property ' Name of the GraphicsLayer Private Property LayerName() As String Get Return TryCast(Me.StateManager.GetProperty("ResultsLayerName"), String) End Get Set(ByVal value As String) Me.StateManager.SetProperty("ResultsLayerName", value) End Set End Property ' Stores the width of the panel's contents Private Property ContentWidth() As Integer Get Return If(StateManager.GetProperty("ContentWidth") Is Nothing, 0, CInt(Fix(StateManager.GetProperty("ContentWidth")))) End Get Set(ByVal value As Integer) StateManager.SetProperty("ContentWidth", value) End Set End Property ' Stores the height of the panel's contents Private Property ContentHeight() As Integer Get Return If(StateManager.GetProperty("ContentHeight") Is Nothing, 0, CInt(Fix(StateManager.GetProperty("ContentHeight")))) End Get Set(ByVal value As Integer) StateManager.SetProperty("ContentHeight", value) End Set End Property #End Region #Region "ASP.NET WebControl Life Cycle Event Handlers - CreateChildControls" ' Creates the panel interface Protected Overrides Sub CreateChildControls() Controls.Clear() MyBase.CreateChildControls() ' If the panel does not have an associated GraphicsLayer, exit the function If Me.GraphicsLayer Is Nothing Then Return End If ' Create a div to hold all the panel's content Dim contentDiv As New System.Web.UI.HtmlControls.HtmlGenericControl("div") contentDiv.ID = "ContentDiv" contentDiv.Style(System.Web.UI.HtmlTextWriterStyle.Overflow) = "auto" ' If the content height and width have already been calculated, apply them to the ' content div If Me.ContentWidth > 0 Then contentDiv.Style(System.Web.UI.HtmlTextWriterStyle.Width) = String.Format("{0}px", Me.ContentWidth.ToString()) End If If Me.ContentHeight > 0 Then contentDiv.Style(System.Web.UI.HtmlTextWriterStyle.Height) = String.Format("{0}px", Me.ContentHeight.ToString()) End If ' Add the div to the task's controls collection Me.Controls.Add(contentDiv) ' Create a table to store the task results and initialize its styling Dim resultsTable As New System.Web.UI.WebControls.Table() resultsTable.ID = "ContentTable" resultsTable.Style("border-right") = "silver 2px solid" resultsTable.Style("border-bottom") = "silver 2px solid" resultsTable.CellPadding = 0 ' If the content height and width have already been calculated, apply them to the ' results table If Me.ContentWidth > 0 Then resultsTable.Style(System.Web.UI.HtmlTextWriterStyle.Width) = String.Format("{0}px", Me.ContentWidth.ToString()) End If If Me.ContentHeight > 0 Then resultsTable.Style(System.Web.UI.HtmlTextWriterStyle.Height) = String.Format("{0}px", Me.ContentHeight.ToString()) End If ' Add the table to the content div contentDiv.Controls.Add(resultsTable) ' Get the indexes of the columns to be displayed Dim displayColumnIndexList As System.Collections.Generic.List(Of Integer) = Me.GetDisplayColumnIndexes() Dim columnWidthList As New System.Collections.Generic.List(Of Single)() Dim rowHeightList As New System.Collections.Generic.List(Of Single)() ' Create a header row and add it to the table resultsTable.Rows.Add(Me.CreateHeaderRow(displayColumnIndexList, columnWidthList, rowHeightList)) ' Create data rows and add them to the table resultsTable.Rows.AddRange(Me.CreateDataRows(displayColumnIndexList, columnWidthList, rowHeightList)) ' Calculate the table width by summing the stored widths of the text of each column, then adding the ' width of each column's border. Dim tableWidth As Single = 0 For Each columnWidth As Single In columnWidthList tableWidth += columnWidth Next columnWidth tableWidth += columnWidthList.Count * 2 tableWidth = CSng(System.Math.Round(tableWidth + 0.5)) ' Calculate the table height by summing the stored heights of the text of each row, then adding the ' height of each column's border. Dim tableHeight As Single = 0 For Each rowHeight As Single In rowHeightList tableHeight += rowHeight * 2 Next rowHeight tableHeight += rowHeightList.Count tableHeight = CSng(System.Math.Round(tableHeight + 0.5)) ' Apply the calculated dimensions to the task, the content div, and the table containing the results If tableWidth > 0 AndAlso tableHeight > 0 Then Me.Width = New System.Web.UI.WebControls.Unit(tableWidth, System.Web.UI.WebControls.UnitType.Pixel) Me.Height = New System.Web.UI.WebControls.Unit(tableHeight, System.Web.UI.WebControls.UnitType.Pixel) contentDiv.Style(System.Web.UI.HtmlTextWriterStyle.Width) = Me.Width.ToString() contentDiv.Style(System.Web.UI.HtmlTextWriterStyle.Height) = Me.Height.ToString() resultsTable.Style(System.Web.UI.HtmlTextWriterStyle.Width) = Me.Width.ToString() resultsTable.Style(System.Web.UI.HtmlTextWriterStyle.Height) = Me.Height.ToString() End If If Me.Page.IsCallback Then ' Apply the size on the client by passing the calculated dimensions to the task's size property Dim resizePanelJavaScript As String = "$find('{0}').set_size('{1}', '{2}')" resizePanelJavaScript = String.Format(resizePanelJavaScript, Me.ClientID, Me.Width.ToString(), Me.Height.ToString()) Dim resizePanelCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(resizePanelJavaScript) End If End Sub #End Region #Region "Public Methods" ' Updates the panel contents with the data of the passed-in layer. Public Sub SetLayer(ByVal featureGraphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer, ByVal resourceName As String, ByVal mapID As String) ' Validate method input If featureGraphicsLayer Is Nothing OrElse String.IsNullOrEmpty(resourceName) OrElse String.IsNullOrEmpty(mapID) Then Return End If ' Set the member variable holding a reference to the panel's GraphicsLayer _resultsGraphicsLayer = featureGraphicsLayer ' Set private properties Me.ResourceName = resourceName Me.LayerName = featureGraphicsLayer.TableName Me.MapID = mapID ' Call CreateChildControls to reconstruct the panel's contents Me.CreateChildControls() Me.Refresh() End Sub ' Adds the JavaScript necessary to initialize the panel on the client to the panel's callback results ' collection. Necessary when a panel is being dynamically added at run time. Public Sub InitializeOnClient(ByVal parentControl As System.Web.UI.WebControls.WebControl, ByVal callbackFunctionString As String) ' Get the URLs of the images for the panel's expand and collapse buttons Dim expandedImageUrl As String = ESRI.ArcGIS.ADF.Web.UI.WebControls.ResourceUtility.GetImage("collapse.png", Me, GetType(ESRI.ArcGIS.ADF.Web.UI.WebControls.FloatingPanel), "Runtime") Dim collapsedImageUrl As String = ESRI.ArcGIS.ADF.Web.UI.WebControls.ResourceUtility.GetImage("expand.png", Me, GetType(ESRI.ArcGIS.ADF.Web.UI.WebControls.FloatingPanel), "Runtime") ' Get the panel's HTML and remove characters that will prevent it from being interpreted correctly ' on the client. Dim taskResultsPanelHtml As String = Me.GetControlHtml(Me) taskResultsPanelHtml = taskResultsPanelHtml.Replace("""", "\""") taskResultsPanelHtml = taskResultsPanelHtml.Replace(Constants.vbCr, "") taskResultsPanelHtml = taskResultsPanelHtml.Replace(Constants.vbLf, "") ' Construct JavaScript to update the panel's HTML and create an AJAX component for the panel Dim initTaskResultsPanelJavaScript As String = "" & ControlChars.CrLf & " var parentControl = $get('{0}');" & ControlChars.CrLf & " var row = parentControl.insertRow(parentControl.rows.length);" & ControlChars.CrLf & " var cell = row.insertCell(0);" & ControlChars.CrLf & " cell.innerHTML = ""{1}"";" & ControlChars.CrLf & " var taskResultsPanel = $create(ESRI.ADF.Samples.CustomTasks.TaskResultsPanel,{{ 'id':'{2}', " & ControlChars.CrLf & " 'transparency':{3},'callbackFunctionString':""{4}"", 'forcePNG':true, 'isDocked':false, " & ControlChars.CrLf & " 'initialMaxWidth':'{5}', 'initialMaxHeight':'{6}', 'expandedImage':'{7}', " & ControlChars.CrLf & " 'collapsedImage':'{8}' }},null,null, $get('{2}'));" initTaskResultsPanelJavaScript = String.Format(initTaskResultsPanelJavaScript, parentControl.ClientID, taskResultsPanelHtml, Me.ClientID, Me.Transparency, callbackFunctionString, Me.InitialMaxWidth.ToString(), Me.InitialMaxHeight.ToString(), expandedImageUrl, collapsedImageUrl) ' Embed the JavaScript in a callback result and add it to the panel's collection Dim initTaskResultsPanelCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(initTaskResultsPanelJavaScript) Me.CallbackResults.Add(initTaskResultsPanelCallbackResult) End Sub ' Registers JavaScript files required by the class. This method allows external classes to register these ' scripts in situations where this class will not be able to (i.e. when TaskResultsPanels are only created ' dynamically at run time) Public Shared Sub RegisterScripts(ByVal registeringControl As ESRI.ArcGIS.ADF.Web.UI.WebControls.CompositeControl) If (Not registeringControl.Page.ClientScript.IsStartupScriptRegistered("TaskResultsPanelScript")) Then registeringControl.Page.ClientScript.RegisterStartupScript(registeringControl.GetType(), "TaskResultsPanelScript", FindNearTask_VBNet.ResourceUtility.GetJavascript(registeringControl, "TaskResultsPanel.js", registeringControl.GetType())) End If End Sub #End Region #Region "Private Methods" #Region "Table Creation Methods" Private Function GetDisplayColumnIndexes() As System.Collections.Generic.List(Of Integer) Dim DisplayColumnIndexList As New System.Collections.Generic.List(Of Integer)() ' Get the contents template for the panel's associated GraphicsLayer. This will contain ' information about the layer's display columns. Dim layerContentsTemplate As String = Me.GraphicsLayer.GetContentsTemplate(True, System.Drawing.Color.White, True, Nothing) ' Iterate through the GraphicsLayer's columns building a list of the indexes of those that ' are to be displayed For i As Integer = 0 To Me.GraphicsLayer.Columns.Count - 1 ' Get the curernt column Dim currentColumn As System.Data.DataColumn = Me.GraphicsLayer.Columns(i) ' Get the column's visibility from its extended properties Dim visibility As String = TryCast(currentColumn.ExtendedProperties(ESRI.ArcGIS.ADF.Web.Constants.ADFVisibility), String) ' Get the display name of the field Dim fieldName As String = If((Not String.IsNullOrEmpty(currentColumn.Caption)), currentColumn.Caption, currentColumn.ColumnName) ' If the column is not supposed to be displayed, skip to the next If (visibility IsNot Nothing AndAlso (Not System.Convert.ToBoolean(visibility))) OrElse currentColumn.DataType Is GetType(ESRI.ArcGIS.ADF.Web.Geometry.Geometry) OrElse ((Not layerContentsTemplate.Contains(fieldName))) Then Continue For End If ' Add the current column index to the list DisplayColumnIndexList.Add(i) Next i Return DisplayColumnIndexList End Function ' Creates the header row for the panel's data table Private Function CreateHeaderRow(ByVal displayColumnIndexList As System.Collections.Generic.List(Of Integer), ByRef columnWidthList As System.Collections.Generic.List(Of Single), ByRef rowHeightList As System.Collections.Generic.List(Of Single)) As System.Web.UI.WebControls.TableRow Dim tableRow As New System.Web.UI.WebControls.TableRow() ' Create the column for checkoxes to allow for selection/deselection of results If Me.GraphicsLayer IsNot Nothing Then ' Initialize a cell for the column header Dim tableCell As New System.Web.UI.WebControls.TableCell() tableCell.Style("border-right") = "silver 2px solid" tableCell.Style("border-bottom") = "silver 2px solid" tableCell.Style(System.Web.UI.HtmlTextWriterStyle.WhiteSpace) = "nowrap" ' Copy the task's font to the cell Me.CopyFont(tableCell.Font, Me.Font) tableCell.Font.Bold = True tableCell.Text = "Selected" ' Add the cell to the header row tableRow.Cells.Add(tableCell) ' Get the width and height of the text in the cell and add these to the row height ' and column width lists Dim cellSize As System.Drawing.SizeF = Me.GetTextScreenSize(tableCell.Text, tableCell.Font) rowHeightList.Add(cellSize.Height) columnWidthList.Add(cellSize.Width) End If ' Loop through the display column indexes, making a header cell for each For Each index As Integer In displayColumnIndexList ' Initialize a cell for the column header Dim tableCell As New System.Web.UI.WebControls.TableCell() tableCell.Style("border-right") = "silver 2px solid" tableCell.Style("border-bottom") = "silver 2px solid" tableCell.Style(System.Web.UI.HtmlTextWriterStyle.WhiteSpace) = "nowrap" ' Copy the task's font to the cell Me.CopyFont(tableCell.Font, Me.Font) tableCell.Font.Bold = True ' Add the cell to the header row tableRow.Cells.Add(tableCell) ' If the current column has a caption, use that as the header text. Otherwise, use the ' column name. We do this because the Web ADF stores display aliases column captions. Dim currentColumn As System.Data.DataColumn = Me.GraphicsLayer.Columns(index) tableCell.Text = If((String.IsNullOrEmpty(currentColumn.Caption)), currentColumn.ColumnName, currentColumn.Caption) ' Get the width and height of the text in the cell and add these to the row height ' and column width lists Dim cellSize As System.Drawing.SizeF = Me.GetTextScreenSize(tableCell.Text, tableCell.Font) rowHeightList(0) = If(cellSize.Height > rowHeightList(0), cellSize.Height, rowHeightList(0)) columnWidthList.Add(cellSize.Width) Next index Return tableRow End Function ' Creates the data rows for the panel's data table Private Function CreateDataRows(ByVal displayColumnIndexList As System.Collections.Generic.List(Of Integer), ByRef columnWidthList As System.Collections.Generic.List(Of Single), ByRef rowHeightList As System.Collections.Generic.List(Of Single)) As System.Web.UI.WebControls.TableRow() ' JavaScript to highlight and un-highlight the table row and corresponding graphic feature. ' Wired to mouseover and mouseout. Dim setHighlightJavaScript As String = "" & ControlChars.CrLf & " try {{" & ControlChars.CrLf & " this.style.backgroundColor = '{0}';" & ControlChars.CrLf & " var graphicFeatureGroup = $find('{1}');" & ControlChars.CrLf & " var graphicFeature = graphicFeatureGroup.get({2});" & ControlChars.CrLf & " graphicFeature.set_highlight({3});" & ControlChars.CrLf & " }}" & ControlChars.CrLf & " catch (ex) {{" & ControlChars.CrLf & " }}" ' JavaScript to zoom to the feature corresponding to the clicked row. Dim zoomToFeatureJavaScript As String = "" & ControlChars.CrLf & " try {{" & ControlChars.CrLf & " // Get the envelope of the feature" & ControlChars.CrLf & " var map = $find('{0}');" & ControlChars.CrLf & " var graphicFeatureGroup = $find('{1}');" & ControlChars.CrLf & " var graphicFeature = graphicFeatureGroup.get({2});" & ControlChars.CrLf & " var geometry = graphicFeature.get_geometry();" & ControlChars.CrLf & " var envelope = geometry.getEnvelope();" & ControlChars.CrLf & ControlChars.CrLf & " // Expand the envelope so some area round the feature is included" & ControlChars.CrLf & " var envelopeDivisor = 3;" & ControlChars.CrLf & " var xExpansionFactor = envelope.get_width() / envelopeDivisor;" & ControlChars.CrLf & " var yExpansionFactor = envelope.get_height() / envelopeDivisor;" & ControlChars.CrLf & ControlChars.CrLf & " // Update the envelope with the expansion factor" & ControlChars.CrLf & " var xMax = envelope.get_xmax() + xExpansionFactor;" & ControlChars.CrLf & " envelope.set_xmax(xMax);" & ControlChars.CrLf & ControlChars.CrLf & " var xMin = envelope.get_xmin() - xExpansionFactor;" & ControlChars.CrLf & " envelope.set_xmin(xMin);" & ControlChars.CrLf & ControlChars.CrLf & " var yMax = envelope.get_ymax() + yExpansionFactor;" & ControlChars.CrLf & " envelope.set_ymax(yMax);" & ControlChars.CrLf & ControlChars.CrLf & " var yMin = envelope.get_ymin() - yExpansionFactor;" & ControlChars.CrLf & " envelope.set_ymin(yMin);" & ControlChars.CrLf & ControlChars.CrLf & " // Zoom the map to the envelope" & ControlChars.CrLf & " map.zoomToBox(envelope, false);" & ControlChars.CrLf & " }}" & ControlChars.CrLf & " catch (ex) {{" & ControlChars.CrLf & " }}" ' JavaScript to toggle whether or not a feature is selected. Wired to each checkbox's onclick event. Dim toggleFeatureJavaScript As String = "" & ControlChars.CrLf & " try {{" & ControlChars.CrLf & " var graphicFeatureGroup = $find('{0}');" & ControlChars.CrLf & " var graphicFeature = graphicFeatureGroup.get({1});" & ControlChars.CrLf & " graphicFeature.set_isSelected($get('{2}').checked);" & ControlChars.CrLf & " }}" & ControlChars.CrLf & " catch (ex) {{" & ControlChars.CrLf & " }}" ' Get the client ID of the GraphicsLayer associated with the panel Dim graphicsLayerClientID As String = Me.MapInstance.GetGraphicsLayerClientID(Me.GraphicsLayer) Dim tableRowArray(Me.GraphicsLayer.Rows.Count - 1) As System.Web.UI.WebControls.TableRow Dim tableRow As System.Web.UI.WebControls.TableRow ' Loop through the rows (i.e. features) in the GraphicsLayer, creating a row in the rows array for each For i As Integer = 0 To Me.GraphicsLayer.Rows.Count - 1 ' Create a new row and add it to the rows array tableRow = New System.Web.UI.WebControls.TableRow() tableRowArray(i) = tableRow ' Wire the row's onmouseover and onmouseout events to the JavaScript that applies and removes row and ' feature highlighting tableRow.Attributes.Add("onmouseover", String.Format(setHighlightJavaScript, "gray", graphicsLayerClientID, i, "true")) tableRow.Attributes.Add("onmouseout", String.Format(setHighlightJavaScript, "white", graphicsLayerClientID, i, "false")) ' Wire the row's onclick event to the JavaScript that will zoom the map to the coresponding graphic feature tableRow.Attributes.Add("onclick", String.Format(zoomToFeatureJavaScript, Me.MapInstance.ClientID, graphicsLayerClientID, i)) ' Change the mouse cursor to ta pointer when the row is hovered over so users know clicking it will do ' something tableRow.Style(System.Web.UI.HtmlTextWriterStyle.Cursor) = "pointer" ' Get the current row (feature) from the GraphicsLayer Dim currentRow As System.Data.DataRow = Me.GraphicsLayer.Rows(i) ' Create a cell to hold the checkbox that toggles whether the corresponding feature is selected If GraphicsLayer IsNot Nothing Then ' Instantiate and initialize the styling of the cell Dim tableCell As New System.Web.UI.WebControls.TableCell() tableCell.Style("border-right") = "silver 2px solid" tableCell.Style("border-bottom") = "silver 2px solid" tableCell.Style(System.Web.UI.HtmlTextWriterStyle.WhiteSpace) = "nowrap" ' Add the cell to the current row tableRow.Cells.Add(tableCell) ' Create a checkbox and set its ID to the current row index. This row index corresponds to ' the ID of the graphic feature required to retrieve that feature through the Web ADF JavaScript ' GraphicFeatureGroup::get function. Dim checkBox As New System.Web.UI.HtmlControls.HtmlInputCheckBox() checkBox.ID = i.ToString() ' Set the checked state of the checkbox based on the selected state of the current feature checkBox.Checked = System.Convert.ToBoolean(currentRow(GraphicsLayer.IsSelectedColumn)) ' Wire the JavaScript to toggle the selected state of the corresponding feature to the ' checkbox's onclick event Dim clientAction As String = String.Format(toggleFeatureJavaScript, graphicsLayerClientID, i, checkBox.ClientID) checkBox.Attributes.Add("onclick", clientAction) ' Add the checkbox to the current cell tableCell.Controls.Add(checkBox) End If ' Initialize column index and row index variables that are used to traverse the lists containing ' the table's column widths and row heights. Dim columnIndex As Integer = 1 Dim rowIndex As Integer = i + 1 ' Loop through the indexes of the display columns creating a table cell and adding the ' corresponding feature data for each For Each index As Integer In displayColumnIndexList ' Instantiate the cell and initialize its styling Dim tableCell As New System.Web.UI.WebControls.TableCell() tableCell.Style("border-right") = "silver 2px solid" tableCell.Style("border-bottom") = "silver 2px solid" tableCell.Style(System.Web.UI.HtmlTextWriterStyle.WhiteSpace) = "nowrap" ' Apply the task's font to the cell Me.CopyFont(tableCell.Font, Me.Font) tableCell.Font.Bold = False ' Add the cell to the current row tableRow.Cells.Add(tableCell) ' Set the cell's text to the value of the corresponding attribute for the current feature tableCell.Text = currentRow(index).ToString() ' Add content to empty cells so they are still formatted If String.IsNullOrEmpty(tableCell.Text) Then tableCell.Text = " " End If ' Get the size of the cell given its text Dim cellSize As System.Drawing.SizeF = Me.GetTextScreenSize(tableCell.Text, tableCell.Font) ' Only update the row height if the current row height has not been initialized or the height ' of the current cell is greater than the stored row height If columnIndex = 1 Then rowHeightList.Add(cellSize.Height) Else rowHeightList(rowIndex) = If(cellSize.Height > rowHeightList(rowIndex), cellSize.Height, rowHeightList(rowIndex)) End If ' Only update the column width if the width of the current cell is greater than the stored ' column width columnWidthList(columnIndex) = If(cellSize.Width > columnWidthList(columnIndex), cellSize.Width, columnWidthList(columnIndex)) columnIndex += 1 Next index Next i Return tableRowArray End Function #End Region ' Retrieves the GraphicsLayer associated with the panel based on the MapInstance, ResourceName, and ' LayerName properties Private Function GetGraphicsLayer() As ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer Dim featureGraphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer = Nothing ' Make sure a resource name and layer name have been defined. These are initialized in SetLayer. If (Not String.IsNullOrEmpty(Me.ResourceName)) AndAlso (Not String.IsNullOrEmpty(Me.LayerName)) Then ' Get the resource item corresponding to the resource name Dim mapResourceItem As ESRI.ArcGIS.ADF.Web.UI.WebControls.MapResourceItem = Me.MapInstance.MapResourceManagerInstance.ResourceItems.Find(Me.ResourceName) ' Make sure the resource item was found If mapResourceItem IsNot Nothing AndAlso mapResourceItem.Resource IsNot Nothing Then ' Get a reference to the resource underlying the resource item as a graphics resource Dim graphicsResource As ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource = TryCast(mapResourceItem.Resource, ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource) ' Make sure the resource could be referenced as a graphics resource If graphicsResource IsNot Nothing Then ' Loop through the tables and find the one matching the panel's layer name. This will be ' the associated GraphicsLayer. For Each table As System.Data.DataTable In graphicsResource.Graphics.Tables If table.TableName = Me.LayerName Then featureGraphicsLayer = TryCast(table, ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer) Exit For End If Next table End If End If End If Return featureGraphicsLayer End Function ' Gets the screen size of the passed-in text in the passed-in font Private Function GetTextScreenSize(ByVal text As String, ByVal fontInfo As System.Web.UI.WebControls.FontInfo) As System.Drawing.SizeF Dim size As System.Drawing.SizeF Dim emSize As Single = System.Convert.ToSingle(fontInfo.Size.Unit.Value + 1) emSize = If(emSize = 0, 12, emSize) Dim font As New System.Drawing.Font(fontInfo.Name, emSize) Dim bitmap As New System.Drawing.Bitmap(1000, 100) Dim graphics As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(bitmap) size = graphics.MeasureString(text, font) graphics.Dispose() Return size End Function ' Copies the properties of one FontInfo to another Private Sub CopyFont(ByVal targetFont As System.Web.UI.WebControls.FontInfo, ByVal sourceFont As System.Web.UI.WebControls.FontInfo) targetFont.Bold = sourceFont.Bold targetFont.Italic = sourceFont.Italic targetFont.Name = sourceFont.Name targetFont.Names = sourceFont.Names targetFont.Overline = sourceFont.Overline targetFont.Size = sourceFont.Size targetFont.Strikeout = sourceFont.Strikeout targetFont.Underline = sourceFont.Underline End Sub ' Retrieves the HTML of a WebControl Private Function GetControlHtml(ByVal webControl As System.Web.UI.Control) As String ' Instantaite an HtmlTextWriter object Dim stringWriter As New System.IO.StringWriter() Dim htmlTextWriter As New System.Web.UI.HtmlTextWriter(stringWriter) ' Render the passed-in control's html to the HtmlTextWriter webControl.RenderControl(htmlTextWriter) ' Get the control's html as a string Return stringWriter.ToString() End Function #End Region End Class End Namespace