College.NET Source Code - AnchorCloud Sample

The central component of the College.NET application is the AnchorCloud control. It is a databound custom web control that renders a cloud/grid of hyperlinks with appropriate tooltips, comments, and formatting.   All source code markup was produced by the excellent CopySourceAsHtml Visual Studio 2005 Add-In.


    1 Imports System
    2 Imports System.Web
    3 Imports System.Web.UI.WebControls
    4 
    5 '// The AnchorCloud control is a Databound control.
    6 '// It is bound to the results of the qCollegeReflections query.
    7 '// It renders the underlying data as a grid/cloud of hyperlinks.
    8 '// The control also tries to minimize the size of the output by tracking style changes.
    9 
   10 <ToolboxData("<{0}:AnchorCloud runat=server></{0}:AnchorCloud>")> _
   11 Public Class AnchorCloud
   12     Inherits DataBoundControl
   13 
   14     Public Enum RenderStyles
   15         Cloud = 0
   16         Grid = 1
   17     End Enum
   18 
   19     '// Public property placeholders
   20     Private _renderStyle As RenderStyles
   21 
   22     '// Support Databound control properties
   23     Private _data As IEnumerable
   24     Private _dataTextField As String = String.Empty
   25     Private _sortExpression As String = String.Empty
   26 
   27     '// Non-breaking hyphen depends on browser type
   28     '// Calculate it once, then store it here
   29     Private _nonBreakingHyphen As String
   30 
   31 
   32     '// Specify how the the control is rendered.
   33     '// Valid choices are to render as a grid or as a cloud (of hyperlinks)
   34     Public Property RenderStyle() As RenderStyles
   35         Get
   36             Return _renderStyle
   37         End Get
   38         Set(ByVal value As RenderStyles)
   39             _renderStyle = value
   40         End Set
   41     End Property
   42 
   43 
   44     '// Specify how to sort the output from the underlying data object
   45     '// Value is passed through to underlying databound control methods
   46     Public Property SortExpression() As String
   47         Get
   48             Return _sortExpression
   49         End Get
   50         Set(ByVal value As String)
   51             _sortExpression = value
   52         End Set
   53     End Property
   54 
   55 
   56     '// Override WebControl.RenderContents
   57     '// Call the appropriate routine, depending on the render mode.
   58     Protected Overrides Sub RenderContents(ByVal writer As HtmlTextWriter)
   59         PrepareNonBreakingHyphen(writer)
   60 
   61         If DesignMode Then
   62             RenderDesigner(writer)
   63             Return
   64         End If
   65 
   66         Select Case RenderStyle
   67             Case RenderStyles.Grid
   68                 RenderGrid(writer)
   69             Case Else
   70                 RenderCloud(writer)
   71         End Select
   72     End Sub
   73 
   74 
   75     '// Override of DataBoundControl.PerformSelect method
   76     '// Bind the control to the specified datasource
   77     Protected Overrides Sub PerformSelect()
   78         '// This is the Microsoft recommended approach to implementing a databound control.
   79         '// It would be better if it were encapsulated in a class/interface.
   80         '// However, since this is a one-off project, just use it directly.
   81 
   82         Dim dataSourceSelectArguments As DataSourceSelectArguments
   83         Dim dataSourceView As DataSourceView
   84 
   85         If Not IsBoundUsingDataSourceID Then
   86             Me.OnDataBinding(EventArgs.Empty)
   87         End If
   88 
   89         dataSourceView = Me.GetData()
   90 
   91         dataSourceSelectArguments = New DataSourceSelectArguments
   92         If dataSourceView.CanSort = True Then
   93             If Me.SortExpression.Length > 0 Then
   94                 dataSourceSelectArguments.SortExpression = Me.SortExpression
   95             End If
   96         End If
   97 
   98         dataSourceView.Select(dataSourceSelectArguments, AddressOf PerformDataBinding)
   99 
  100         RequiresDataBinding = False
  101         MarkAsDataBound()
  102         OnDataBound(EventArgs.Empty)
  103     End Sub
  104 
  105     '// Override DataBoundControl.PerformDataBinding
  106     '// This is called when the asynchronous DataSourceView.Select() method completes
  107     Protected Overrides Sub PerformDataBinding(ByVal data As System.Collections.IEnumerable)
  108         MyBase.PerformDataBinding(data)
  109 
  110         '// Store a local copy of the data for later use
  111         _data = data
  112     End Sub
  113 
  114 
  115     '// Render design mode version of control (silver block with control ID)
  116     Private Sub RenderDesigner(ByVal writer As HtmlTextWriter)
  117         writer.Write("<table cellpadding=4 cellspacing=0 bordercolor=black border=1>")
  118         writer.Write("<tr>")
  119         writer.Write("<td bgcolor=silver>")
  120         writer.Write("<b>AnchorCloud</b> - " & Me.ID)
  121         If Me.DataSourceID.Length > 0 Then
  122             writer.Write(" (DataBound - " & HttpUtility.HtmlEncode(Me.DataSourceID) & ")")
  123         Else
  124             writer.Write(" (Unbound)")
  125         End If
  126         writer.Write("</td></tr></table></span>")
  127         Exit Sub
  128     End Sub
  129 
  130 
  131     '// Render contents of control as a Cloud (series of Html Hyperlinks)
  132     Private Sub RenderCloud(ByVal writer As HtmlTextWriter)
  133         Dim dataElement As Object
  134 
  135         Dim reflectionID As Integer
  136         Dim rating As Integer
  137         Dim shortName As String
  138         Dim hyperlink As String
  139         Dim tooltip As String
  140         Dim course As String
  141 
  142         Dim fontSize As Integer
  143         Dim fontBold As Boolean
  144         Dim lastFontSize As Integer
  145         Dim fontNeedsEndTag As Boolean
  146 
  147         Dim htmlClass As String
  148 
  149         writer.BeginRender()
  150 
  151         writer.AddAttribute("class", "CloudView", False)
  152         writer.RenderBeginTag("span")
  153 
  154         If Not _data.GetEnumerator.MoveNext() Then
  155             writer.Write("No records match your criteria")
  156         End If
  157 
  158         fontSize = 3
  159         lastFontSize = 3
  160         fontBold = False
  161         writer.AddAttribute("size", CStr(fontSize), False)
  162         writer.RenderBeginTag("font")
  163         fontNeedsEndTag = False
  164 
  165         For Each dataElement In _data
  166             reflectionID = CInt(DataBinder.GetPropertyValue(dataElement, "ReflectionID"))
  167             rating = CInt(DataBinder.GetPropertyValue(dataElement, "Rating"))
  168             shortName = CStrSafe(DataBinder.GetPropertyValue(dataElement, "ShortName"))
  169             hyperlink = CStrSafe(DataBinder.GetPropertyValue(dataElement, "Hyperlink"))
  170             course = CStrSafe(DataBinder.GetPropertyValue(dataElement, "CourseNumber")) & " - " & CStrSafe(DataBinder.GetPropertyValue(dataElement, "CourseName"))
  171             tooltip = CStrSafe(DataBinder.GetPropertyValue(dataElement, "Tooltip"))
  172             If tooltip.Length > 0 Then
  173                 tooltip = tooltip & " (" & course & ")"
  174             Else
  175                 tooltip = course
  176             End If
  177 
  178             htmlClass = "R" & rating
  179             fontSize = 3
  180             fontBold = False
  181             Select Case rating
  182                 Case 1
  183                     fontSize = 3
  184                     fontBold = True
  185                 Case 2
  186                     fontSize = 4
  187                     fontBold = False
  188                 Case 3
  189                     fontSize = 4
  190                     fontBold = True
  191                 Case 4
  192                     fontSize = 5
  193                     fontBold = True
  194                 Case 5
  195                     fontSize = 6
  196                     fontBold = True
  197             End Select
  198 
  199             If fontSize > 6 Then
  200                 fontSize = 6
  201             End If
  202 
  203             If fontSize <> lastFontSize Then
  204                 If fontNeedsEndTag Then
  205                     writer.RenderEndTag() '// font
  206                     fontNeedsEndTag = False
  207                     lastFontSize = 3
  208                 End If
  209             End If
  210 
  211             writer.Write(" &nbsp;&nbsp; ")
  212             writer.Write(vbNewLine)
  213 
  214             If fontSize <> lastFontSize Then
  215                 writer.AddAttribute("size", CStr(fontSize), False)
  216                 writer.RenderBeginTag("font")
  217                 fontNeedsEndTag = True
  218                 lastFontSize = fontSize
  219             End If
  220 
  221             If fontBold Then
  222                 writer.RenderBeginTag("b")
  223             End If
  224 
  225             If hyperlink.Length > 0 Then
  226                 writer.AddAttribute("href", hyperlink, True)
  227                 If tooltip.Length > 0 Then
  228                     writer.AddAttribute("title", tooltip, True)
  229                 End If
  230                 writer.AddAttribute("class", htmlClass, False)
  231 
  232                 writer.RenderBeginTag("a")
  233                 writer.Write(HtmlEncodedNonBreakingText(shortName))
  234                 writer.RenderEndTag()
  235             Else
  236                 If tooltip.Length > 0 Then
  237                     writer.AddAttribute("class", htmlClass, False)
  238                     writer.AddAttribute("title", tooltip, True)
  239                     writer.RenderBeginTag("span")
  240                     writer.RenderBeginTag("u")
  241                 End If
  242 
  243                 writer.Write(HtmlEncodedNonBreakingText(shortName))
  244 
  245                 If tooltip.Length > 0 Then
  246                     writer.RenderEndTag() '// u
  247                     writer.RenderEndTag() '// span
  248                 End If
  249             End If
  250 
  251             If fontBold Then
  252                 writer.RenderEndTag() '// b
  253             End If
  254 
  255             writer.Flush()
  256         Next
  257 
  258         If fontNeedsEndTag Then
  259             writer.RenderEndTag() '// font
  260         End If
  261 
  262         writer.RenderEndTag() '// font
  263 
  264         writer.RenderEndTag() '// span
  265 
  266         writer.EndRender()
  267     End Sub
  268 
  269 
  270     '// Render contents of control as a Grid (Html Table)
  271     Private Sub RenderGrid(ByVal writer As HtmlTextWriter)
  272         Dim dataElement As Object
  273 
  274         Dim rating As Integer
  275         Dim shortName As String
  276         Dim hyperlink As String
  277         Dim tooltip As String
  278         Dim courseNumber As String
  279         Dim courseName As String
  280         Dim course As String
  281         Dim semester As String
  282 
  283         Dim fontSize As Integer
  284         Dim fontBold As Boolean
  285 
  286         Dim recordCount As Integer
  287 
  288         Dim htmlClass As String
  289 
  290         writer.BeginRender()
  291 
  292         writer.AddAttribute("class", "GridView", False)
  293         writer.RenderBeginTag("span")
  294 
  295         recordCount = 0
  296         If Not _data.GetEnumerator.MoveNext() Then
  297             writer.Write("No records match your criteria")
  298             Return
  299         End If
  300 
  301         writer.AddAttribute("border", "1", False)
  302         writer.AddAttribute("cellpadding", "4", False)
  303         writer.AddAttribute("cellspacing", "0", False)
  304         writer.Write(vbNewLine)
  305         writer.RenderBeginTag("table")
  306 
  307         writer.AddAttribute("bgcolor", "silver", False)
  308         writer.Write(vbNewLine)
  309         writer.RenderBeginTag("thead")
  310 
  311         writer.Write(vbNewLine)
  312         writer.RenderBeginTag("th")
  313         writer.Write("Semester")
  314         writer.RenderEndTag()
  315 
  316         writer.Write(vbNewLine)
  317         writer.RenderBeginTag("th")
  318         writer.Write("Course Number")
  319         writer.RenderEndTag()
  320 
  321         writer.Write(vbNewLine)
  322         writer.RenderBeginTag("th")
  323         writer.Write("Course Name")
  324         writer.RenderEndTag()
  325 
  326         writer.Write(vbNewLine)
  327         writer.RenderBeginTag("th")
  328         writer.Write("Subject")
  329         writer.RenderEndTag()
  330 
  331         writer.Write(vbNewLine)
  332         writer.RenderBeginTag("th")
  333         writer.Write("Description")
  334         writer.RenderEndTag()
  335 
  336         writer.RenderEndTag() '// thead
  337 
  338         For Each dataElement In _data
  339 
  340             recordCount = recordCount + 1
  341 
  342             writer.Write(vbNewLine)
  343             writer.RenderBeginTag("tr")
  344 
  345             rating = CInt(DataBinder.GetPropertyValue(dataElement, "Rating"))
  346             shortName = CStrSafe(DataBinder.GetPropertyValue(dataElement, "ShortName"))
  347             hyperlink = CStrSafe(DataBinder.GetPropertyValue(dataElement, "Hyperlink"))
  348             courseNumber = CStrSafe(DataBinder.GetPropertyValue(dataElement, "CourseNumber"))
  349             courseName = CStrSafe(DataBinder.GetPropertyValue(dataElement, "CourseName"))
  350             course = courseNumber & " - " & courseName
  351             semester = CStrSafe(DataBinder.GetPropertyValue(dataElement, "Semester")) & " " & CStrSafe(DataBinder.GetPropertyValue(dataElement, "Year"))
  352             tooltip = CStrSafe(DataBinder.GetPropertyValue(dataElement, "Tooltip"))
  353 
  354             htmlClass = "R" & rating
  355             fontSize = 3
  356             fontBold = False
  357             Select Case rating
  358                 Case 1
  359                     fontSize = 3
  360                     fontBold = True
  361                 Case 2
  362                     fontSize = 4
  363                     fontBold = False
  364                 Case 3
  365                     fontSize = 4
  366                     fontBold = True
  367                 Case 4
  368                     fontSize = 5
  369                     fontBold = False
  370                 Case 5
  371                     fontSize = 5
  372                     fontBold = True
  373             End Select
  374 
  375             If fontSize > 6 Then
  376                 fontSize = 6
  377             End If
  378 
  379             writer.AddAttribute("valign", "top", False)
  380             writer.Write(vbNewLine)
  381             writer.RenderBeginTag("td")
  382             writer.Write(HtmlEncodedNonBreakingText(semester))
  383             writer.RenderEndTag()
  384 
  385             writer.AddAttribute("valign", "top", False)
  386             writer.Write(vbNewLine)
  387             writer.RenderBeginTag("td")
  388             writer.Write(HtmlEncodedNonBreakingText(courseNumber))
  389             writer.RenderEndTag()
  390 
  391             writer.AddAttribute("valign", "top", False)
  392             writer.Write(vbNewLine)
  393             writer.RenderBeginTag("td")
  394             writer.Write(HttpUtility.HtmlEncode(courseName))
  395             writer.RenderEndTag()
  396 
  397             writer.AddAttribute("valign", "top", False)
  398             writer.Write(vbNewLine)
  399             writer.RenderBeginTag("td")
  400 
  401             If fontSize <> 3 Then
  402                 writer.AddAttribute("size", CStr(fontSize), False)
  403                 writer.RenderBeginTag("font")
  404             End If
  405 
  406             If fontBold Then
  407                 writer.RenderBeginTag("b")
  408             End If
  409 
  410             If hyperlink.Length > 0 Then
  411                 writer.AddAttribute("class", htmlClass, False)
  412                 writer.AddAttribute("href", hyperlink, True)
  413                 writer.RenderBeginTag("a")
  414                 writer.Write(HttpUtility.HtmlEncode(shortName))
  415                 writer.RenderEndTag()
  416             Else
  417                 writer.AddAttribute("class", htmlClass, False)
  418                 writer.RenderBeginTag("span")
  419                 writer.Write(HttpUtility.HtmlEncode(shortName))
  420                 writer.RenderEndTag()
  421             End If
  422 
  423             If fontBold Then
  424                 writer.RenderEndTag() '// b
  425             End If
  426 
  427             If fontSize <> 3 Then
  428                 writer.RenderEndTag() '// font
  429             End If
  430 
  431             writer.RenderEndTag() '// td
  432 
  433             writer.AddAttribute("valign", "top", False)
  434             writer.Write(vbNewLine)
  435             writer.RenderBeginTag("td")
  436             If tooltip.Length > 0 Then
  437                 writer.Write(HttpUtility.HtmlEncode(tooltip))
  438             Else
  439                 writer.Write("&nbsp;")
  440             End If
  441 
  442             writer.RenderEndTag() '// td
  443 
  444             writer.RenderEndTag() '// tr
  445 
  446             writer.Flush()
  447         Next
  448 
  449         writer.RenderEndTag() '// table
  450 
  451         writer.RenderEndTag() '// span
  452 
  453         writer.EndRender()
  454     End Sub
  455 
  456 
  457     '// Prevent output from being wrapped by the browser (keep words together)
  458     Private Function HtmlEncodedNonBreakingText(ByVal text As String) As String
  459         If text.Length = 0 Then
  460             Return String.Empty
  461         End If
  462 
  463         Dim result As String
  464 
  465         result = text
  466 
  467         result = HttpUtility.HtmlEncode(result)
  468         result = Replace(result, " ", "&nbsp;")
  469         result = Replace(result, "-", _nonBreakingHyphen)
  470 
  471         Return result
  472     End Function
  473 
  474     '// String conversion might need to change depending on type.
  475     '// Therefore, encapsulate the function here, just in case it needs to change later
  476     Private Function CStrSafe(ByVal item As Object) As String
  477         Return item.ToString()
  478     End Function
  479 
  480 
  481     '// Not all browsers deal with non-breaking hypens equally.
  482     '// This function will determine the best character to use.
  483     Sub PrepareNonBreakingHyphen(ByVal writer As HtmlTextWriter)
  484         Dim browser As String
  485 
  486         _nonBreakingHyphen = "&#8209;" '// equivalent "&#x2011;"
  487 
  488         '// Check if Browser object is available
  489         If Me.DesignMode OrElse _
  490             Me.Page Is Nothing _
  491             OrElse Me.Page.Request Is Nothing _
  492             OrElse Me.Page.Request.Browser Is Nothing Then
  493 
  494             '// Browser object is not available, exit now.
  495             Return
  496         End If
  497 
  498         '// Determine which browser is being used
  499         browser = Me.Page.Request.Browser.Browser
  500 
  501         '// Choose appropriate non-breaking hyphen character, depending on browser type
  502         Select Case LCase(browser)
  503             Case "ie", "firefox"
  504                 '// These browsers can render non-breaking hyphens.
  505                 '// Therefore, do nothing.
  506             Case Else
  507                 '// Any other browsers might have problems with rendering non-breaking hyphens.
  508                 '// Therefore, use the tilde character instead.
  509                 _nonBreakingHyphen = "~"
  510         End Select
  511     End Sub
  512 End Class



Copyright (C) 2007-2009 by Robert Pinchbeck
All Rights Reserved