Common Select Buffer tool
Common_SelectBufferTool_VBNet\App_Code\CustomControls.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
Namespace CustomComponents
  Public Class ExtendToc
    Inherits ESRI.ArcGIS.ADF.Web.UI.WebControls.Toc
    #Region "Toc Members"

    ' Initialize the Toc's nodes to be selected on click
    Protected Overrides Sub OnPreRender(ByVal eventArgs As System.EventArgs)
      MyBase.OnPreRender(eventArgs)

      Try
        ' Iterate through the map's Toc functionalities
        For Each tocFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.IMapTocFunctionality In Me.GetFunctionalities()
          Dim gisResource As ESRI.ArcGIS.ADF.Web.DataSources.IGISResource = tocFunctionality.Resource

          ' Make sure the resource supports querying
          Dim resourceSupportsQuery As Boolean = gisResource.SupportsFunctionality(GetType(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality))
          If resourceSupportsQuery Then
            ' Get an object to query the resource
            Dim commonQueryFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality = CType(gisResource.CreateFunctionality(GetType(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality), Nothing), ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality)

            ' Use the query functionality to get the queryable layer names and ids from the resource
            Dim layerIDs As String()
            Dim layerNames As String()
            commonQueryFunctionality.GetQueryableLayers(Nothing, layerIDs, layerNames)

            ' The query functionality will not be used anymore, so remove it from the resource and
            ' dispose of it
            gisResource.Functionalities.Remove(commonQueryFunctionality)
            commonQueryFunctionality.Dispose()

            ' Set each node corresponding to a queryable layer to be selected when clicked
            Dim i As Integer = 0
            Do While i < layerNames.Length
               Dim layerNode As ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode = Utility.FindNode(Me, layerNames(i))
               layerNode.ClickBehavior = ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNodeClickBehavior.Selectable
              i += 1
            Loop
          End If
        Next tocFunctionality
      Catch exception As System.Exception
        Me.CallbackResults.Add(Utility.GetErrorCallback(exception))
      End Try
    End Sub

    ' Update the status bar and any associated drop-downs to display the selected layer name
    Protected Overrides Sub OnNodeSelect(ByVal treeViewPlusNodeEventArgs As ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNodeEventArgs)
      Try
        ' Fire the inherited Toc class's OnNodeSelect event
        MyBase.OnNodeSelect(treeViewPlusNodeEventArgs)

        ' Set the session variable tracking the current selection layer
        Dim nodeText As String = treeViewPlusNodeEventArgs.Node.Text
        Me.Page.Session("SelectionLayer") = nodeText

        ' Create a JavaScript callback result to update the browser's status bar with the
        ' name of the selected layer and add to the instance's callback results collection.
        ' Note this only works in Internet Explorer, unless users of other browsers have
        ' explicitly allowed status bar text to be set via javascript.
        Dim jsShowSelectionLayerOnStatusBar As String = String.Format("window.status = 'The active selection layer is: {0}'", nodeText)
        Dim callbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(jsShowSelectionLayerOnStatusBar)
        Me.CallbackResults.Add(callbackResult)

        ' Iterate through the IDs stored in NodeSelectionUpdateControls.  For each ID that refers
        ' to a DropDownList, create a JavaScript callback result to update that list's text to
        ' match the name of the selected layer.
        For Each controlID As String In Me.NodeSelectionUpdateControls
          Dim webControl As System.Web.UI.Control = Utility.FindControl(Me.Page, controlID)
          If TypeOf webControl Is System.Web.UI.WebControls.DropDownList Then
            Dim jsUpdateActiveLayerDropDown As String = String.Format("var dropDown = " & "document.getElementById('{0}');" & Constants.vbLf & "for (var i = 0; i < dropDown.options.length; i++)" & Constants.vbLf & "{{ var option = dropDown.options[i]; " & Constants.vbLf & "if (option.text == '{1}')" & Constants.vbLf & "{{ option.selected = true; }}" & Constants.vbLf & "else " & Constants.vbLf & "{{ option.selected = false; }}" & Constants.vbLf & "}}", webControl.ClientID, nodeText)
            callbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(jsUpdateActiveLayerDropDown)
            Me.CallbackResults.Add(callbackResult)
          End If
        Next controlID
      Catch exception As System.Exception
        Me.CallbackResults.Add(Utility.GetErrorCallback(exception))
      End Try
    End Sub

    ' Enhance the inherited Toc's SelectedNode property by adding logic to display the passed-in
    ' node as selected
    Public Shadows Property SelectedNode() As ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode
      Get
        Return MyBase.SelectedNode
      End Get
      Set
        MyBase.SelectedNode = Value

        ' Fire the OnNodeSelect event to select the passed-in node
        Dim treeViewPlusNodeEventArgs As ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNodeEventArgs = New ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNodeEventArgs(Value)
        OnNodeSelect(treeViewPlusNodeEventArgs)

        ' Refresh the instance's HTML so that the node selection is visibly updated
        Me.RefreshHtml()
      End Set
    End Property

    #End Region

    #Region "Custom ExtendToc Properties"

    ' Stores IDs of controls to update when a node is selected
    Public Property NodeSelectionUpdateControls() As System.Collections.Generic.List(Of String)
      Get
        ' Attempt to retrieve the ID list from state
        Dim NodeSelectionUpdateControlList As System.Collections.Generic.List(Of String) = TryCast(StateManager.GetProperty("NodeSelectionUpdateControls"), System.Collections.Generic.List(Of String))
        ' If the list has not been stored in state, create a new list instance and place it in
        ' state
        If NodeSelectionUpdateControlList Is Nothing Then
          NodeSelectionUpdateControlList = New System.Collections.Generic.List(Of String)()
          StateManager.SetProperty("NodeSelectionUpdateControls", NodeSelectionUpdateControlList)
        End If
        Return NodeSelectionUpdateControlList
      End Get
      Set
        ' Update the ID list stored in state
        StateManager.SetProperty("NodeSelectionUpdateControls", Value)
      End Set
    End Property

    #End Region

    #Region "Custom ExtendToc Methods"

    ' Function to refresh the Toc's html
    Private Sub RefreshHtml()
      Try
        ' Instantiate an HtmlTextWriter object
        Dim stringWriter As System.IO.StringWriter = New System.IO.StringWriter()
        Dim htmlTextWriter As System.Web.UI.HtmlTextWriter = New System.Web.UI.HtmlTextWriter(stringWriter)

        ' Cast the Toc to an ASP.NET web control and render its html to the HtmlTextWriter
        Dim webControl As System.Web.UI.Control = TryCast(Me, System.Web.UI.Control)
        webControl.RenderControl(htmlTextWriter)

        ' Get the Toc's html as a string
        Dim htmlContent As String = stringWriter.ToString()

        ' Close the StringWriter since we are done with it
        stringWriter.Close()

        ' Instantiate and return a callback result with the control and the html.  Instantiating
        ' a callback result with 3 arguments where "content" is the 2nd argument will create a
        ' result instructing the out-of-the-box callback handler (ESRI.ADF.System.processCallbackResult)
        ' to re-render the control specified by the 1st argument with the html contained in the 3rd
        ' argument.
        Me.CallbackResults.Add(ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateSetContent(webControl, htmlContent))
      Catch exception As System.Exception
        Me.CallbackResults.Add(Utility.GetErrorCallback(exception))
      End Try
    End Sub

    #End Region
  End Class
End Namespace