I've posted a few code snippets and some people noticed that there are references to unresolved methods.I am using a few helper classes. This post describes my VB.Net WebFormsHelper class.
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Web.UI.HtmlControls
Imports System.Data
Imports System.Data.SqlClient
Imports System.Text
Imports Microsoft.ApplicationBlocks.Data
Imports FSHelperLib.DataHelper
Imports System.Data.Common
Public Class WebFormsHelper
#Region "DataGrid columns search"
Public Shared Function ColumnByHeaderText(ByVal Columns As DataGridColumnCollection, ByVal HeaderText As String) As DataGridColumn
Dim oRet As DataGridColumn = Nothing
Dim i As Integer = ColumnIndexByHeaderText(Columns, HeaderText)
If i >= 0 Then
oRet = Columns(i)
End If
Return oRet
End Function
Public Shared Function ColumnIndexByHeaderText(ByVal Columns As DataGridColumnCollection, ByVal HeaderText As String) As Integer
For i As Integer = 0 To Columns.Count - 1
If Columns(i).HeaderText = HeaderText Then
Return i
End If
Next i
Return -1
End Function
Public Shared Function ColumnIndexBySortExpression(ByVal Columns As DataGridColumnCollection, ByVal SortExpression As String) As Integer
For i As Integer = 0 To Columns.Count - 1
If Columns(i).SortExpression = SortExpression Then
Return i
End If
Next i
Return -1
End Function
'MNF 6/8/2004 created ColumnByFooterText and ColumnIndexByFooterText
Public Shared Function ColumnByFooterText(ByVal Columns As DataGridColumnCollection, ByVal text As String) As DataGridColumn
Dim oRet As DataGridColumn = Nothing
Dim i As Integer = ColumnIndexByFooterText(Columns, text)
If i >= 0 Then
oRet = Columns(i)
End If
Return oRet
End Function
Public Shared Function ColumnIndexByFooterText(ByVal Columns As DataGridColumnCollection, ByVal text As String) As Integer
For i As Integer = 0 To Columns.Count - 1
If LCase(Columns(i).FooterText) = LCase(text) Then
Return i
End If
Next i
Return -1
End Function
'If not exists return false
Public Shared Function ColumnByFooterVisibleIfExists(ByVal Columns As DataGridColumnCollection, ByVal FooterName As String, ByVal Visible As Boolean) As Boolean
Dim clmn As DataGridColumn = ColumnByFooterText(Columns, FooterName)
Dim bRet As Boolean = False
If IsNothing(clmn) Then
bRet = False
Else
clmn.Visible = Visible
End If
Return bRet
End Function
Public Shared Function ColumnByFooterVisible(ByVal Columns As DataGridColumnCollection, ByVal FooterName As String, ByVal Visible As Boolean) As Boolean
Dim bRet As Boolean = ColumnByFooterVisibleIfExists(Columns, FooterName, Visible)
If bRet Then 'IsNothing(clmn)
Debug.Assert(False)
End If
Return bRet
End Function
'See http://www.mcse.ms/showthread.php?s=&postid=1481861
'Alternative way is to specify ID in controls within the cell and
Public Shared Function CellByHeaderText(ByVal Item As DataGridItem, ByVal HeaderText As String) As TableCell
' Dim gridTable As DataGridTable = Item.Parent 'DataGrid = gridTable.Parent doesn't work because MS declared DataGridTable as private(why?)
Dim grid As DataGrid = Item.NamingContainer
Dim nColumn As Integer = ColumnIndexByHeaderText(grid.Columns, HeaderText)
If nColumn < 0 Then
Return Nothing
Else
Return Item.Cells(nColumn)
End If
End Function
Public Shared Function CellByFooterText(ByVal Item As DataGridItem, ByVal FooterText As String) As TableCell
' Dim gridTable As DataGridTable = Item.Parent 'DataGrid = gridTable.Parent doesn't work because MS declared DataGridTable as private(why?)
Dim grid As DataGrid = Item.NamingContainer
Dim nColumn As Integer = ColumnIndexByFooterText(grid.Columns, FooterText)
If nColumn < 0 Then
Return Nothing
Else
Return Item.Cells(nColumn)
End If
End Function
Public Shared Function CellBySortExpression(ByVal Item As DataGridItem, ByVal SortExpression As String) As TableCell
' Dim gridTable As DataGridTable = Item.Parent 'DataGrid = gridTable.Parent doesn't work because MS declared DataGridTable as private(why?)
Dim grid As DataGrid = Item.NamingContainer
Dim nColumn As Integer = ColumnIndexBySortExpression(grid.Columns, SortExpression)
If nColumn < 0 Then
Return Nothing
Else
Return Item.Cells(nColumn)
End If
End Function
Public Shared Function ParentDataGrid(ByVal Item As DataGridItem) As DataGrid
' Dim gridTable As DataGridTable = Item.Parent 'DataGrid = gridTable.Parent doesn't work because MS declared DataGridTable as private(why?)
Dim grid As DataGrid = Item.NamingContainer
Return grid
End Function
#End Region '"DataGrid columns search"
#Region " datagrid items helpers"
'Separate oveloads for DataGridItem and RepeaterItem
Public Shared Function IsItemNormalOrAlterating(ByVal item As System.Web.UI.WebControls.DataGridItem) As Boolean
Return item.ItemType = ListItemType.Item Or item.ItemType = ListItemType.AlternatingItem
End Function
Public Shared Function IsItemNormalOrAlterating(ByVal item As System.Web.UI.WebControls.RepeaterItem) As Boolean
Return item.ItemType = ListItemType.Item Or item.ItemType = ListItemType.AlternatingItem
End Function
#End Region '//datagrid items helpers
Public Shared Function CurrentPageIndexAdjustIfRequired(ByVal dg As DataGrid, ByVal nCount As Integer) As Boolean
'If the last row on the last page is deleted, the following error can happen: Invalid CurrentPageIndex value. It must be >= 0 and < the PageCount.
'Possible workaround- catch error see http://groups.google.com.au/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=29aa01c1d59b%248257bdc0%243aef2ecf%40TKMSFTNGXA09
'Solution used from http://www.devarticles.com/index2.php?option=content&task=view&id=495&pop=1&page=0&hide_js=1
' Unfortunutely,The actual DataGrid.PageCount is the "old" page count.
' The new page count of the DataGrid control will be set automatically after we bind the Datagrid to the data source
' with new page size set, but it's too late to avoid exception.
' We need the new page count already now to find out the new current page index, so we must calculate it.
Dim nNewPageCount As Integer = CType(Math.Ceiling(nCount / dg.PageSize), Integer)
' get the new current page index
If dg.CurrentPageIndex >= nNewPageCount And nNewPageCount > 0 Then
dg.CurrentPageIndex = nNewPageCount - 1
End If
End Function
#Region "ListLoad"
'see also CacheHelper.LoadToCacheDictionary
Public Shared Sub ListLoad(ByVal lst As System.Web.UI.WebControls.ListControl, ByVal sConnString As String, _
ByVal sSQL As String, _
ByVal sTextColumn As String, ByVal sValueColumn As String, ByVal sToSelectPrompt As String)
'TODO -see also CacheHelper.LoadToCacheAndListControl
If Not IsNothing(sToSelectPrompt) Then
lst.Items.Add(New ListItem(sToSelectPrompt, -1))
End If
Dim rdr As SqlDataReader = Nothing, sTxt As String
Try
rdr = SqlHelper.ExecuteReader(sConnString, CommandType.Text, sSQL)
While rdr.Read
'RemoveNonPreservedSpace is important for Metabuilder.combobox
sTxt = HtmlHelper.RemoveNonPreservedSpace(Trim(Coalesce(rdr.Item(sTextColumn), "")))
lst.Items.Add(New ListItem(sTxt, Coalesce(rdr.Item(sValueColumn), "")))
End While
Finally
If Not rdr Is Nothing Then rdr.Close()
End Try
End Sub
Public Shared Sub ListLoad(ByVal lst As System.Web.UI.WebControls.ListControl, ByVal enumType As Type, ByVal sToSelectPrompt As String)
If Not IsNothing(sToSelectPrompt) Then
lst.Items.Add(New ListItem(sToSelectPrompt, -1))
End If
For Each i As Integer In [Enum].GetValues(enumType)
lst.Items.Add(New ListItem([Enum].GetName(enumType, i), i))
Next i
End Sub
Public Shared Sub ListLoad(ByVal lst As System.Web.UI.WebControls.ListControl, ByVal sListString As String, ByVal Delimeter As String, _
ByVal sToSelectPrompt As String)
If Not IsNullOrEmpty(sToSelectPrompt) Then
lst.Items.Add(New ListItem(sToSelectPrompt, -1))
End If
Dim sValues As String() = sListString.Split(Delimeter)
For Each sValue As String In sValues
lst.Items.Add(New ListItem(sValue))
Next
End Sub
#End Region '"ListLoad"
'Note this overload works only if PlaceHolder belongs to page, not other user control
Public Shared Function LoadAddUserControl(ByVal PlaceHolder As Control, ByVal sAscxName As String) As UserControl
Return LoadAddUserControl(PlaceHolder, sAscxName, Nothing)
End Function
Public Shared Function LoadAddUserControl(ByVal PlaceHolder As Control, ByVal sAscxName As String, ByVal ID As String) As UserControl
Dim ctlToAdd As UserControl
ctlToAdd = PlaceHolder.Page.LoadControl(sAscxName)
If Not (ID Is Nothing) Then
ctlToAdd.ID = ID
End If
PlaceHolder.Controls.Add(ctlToAdd)
Return ctlToAdd
End Function
#Region "Visible/Enabled methods"
'visible doesn't create any html at all, but this make it hidden and keep data in viewState, alternatively use HtmlInputHidden
'TODO overload for HTmlControl
Public Shared Function HideControl(ByVal ctrl As System.Web.UI.WebControls.WebControl) As Boolean
ctrl.Style("visibility") = "hidden"
End Function
'visible doesn't create any html at all
'TODO overload for HTmlControl
Public Shared Function SetChildVisible(ByVal ctrlParent As System.Web.UI.Control, ByVal ClientID As String, ByVal Visible As Boolean) As Boolean
Dim ctrl As Control = ctrlParent.FindControl(ClientID)
If ctrl Is Nothing Then
Debug.Assert(False, "control not found")
Else
ctrl.Visible = Visible
End If
End Function
Public Shared Function SetChildEnabled(ByVal ctrlParent As System.Web.UI.Control, ByVal ClientID As String, ByVal Enabled As Boolean) As Boolean
'TODO Current version works for WebControl only , handle for HTmlControl as well
Dim ctrl As WebControl = ctrlParent.FindControl(ClientID)
If ctrl Is Nothing Then
Debug.Assert(False, "control not found")
Else
ctrl.Enabled = Enabled
End If
End Function
#End Region '//"Visible/Enabled methods"
#Region "HideEmptyRows overload methods"
'called from DetailedListPage to hide rows without data
Public Shared Sub HideEmptyRow(ByVal rdr As DbDataRecord, ByVal item As System.Web.UI.WebControls.RepeaterItem, ByVal ColumnName As String, Optional ByVal trID As String = "")
Dim tr As Control
If trID.Length = 0 Then trID = "tr" & ColumnName
If IsDBNullOrEmpty(rdr(ColumnName)) Then
tr = item.FindControl(trID)
tr.Visible = False
End If
End Sub
Public Shared Sub HideEmptyRowWithLabelControl(ByVal item As System.Web.UI.WebControls.RepeaterItem, ByVal ControlName As String, Optional ByVal trID As String = "")
Dim tr As Control
Dim ctrl As Label = CType(item.FindControl(ControlName), Label)
If trID.Length = 0 Then trID = "tr" & ControlName
If ctrl.Text.Trim.Length = 0 Then
tr = item.FindControl(trID)
If IsNothing(tr) Then
DebugHelper.PrintChildren(item)
Debug.Assert(False, "Unable to find control " & trID)
Else
tr.Visible = False
End If
End If
End Sub
Public Shared Sub HideEmptyRowWithGrid(ByVal item As System.Web.UI.WebControls.RepeaterItem, ByVal ControlName As String, Optional ByVal trID As String = "")
Dim tr As Control
Dim grd As DataGrid = CType(item.FindControl(ControlName), DataGrid)
If trID.Length = 0 Then trID = "tr" & ControlName
If grd.Items.Count = 0 Then
tr = item.FindControl(trID)
If IsNothing(tr) Then
DebugHelper.PrintChildren(item)
Debug.Assert(False, "Unable to find control " & trID)
Else
tr.Visible = False
End If
End If
End Sub
#End Region '"HideEmptyRows overload methods"
'Returns Url from DataGridItem
Public Shared Function GetHyperlinkUrl(ByVal item As System.Web.UI.WebControls.DataGridItem, ByVal ControlName As String) As String
Dim lnk As HyperLink = CType(item.FindControl(ControlName), HyperLink)
If IsNothing(lnk) Then
DebugHelper.PrintChildren(item)
Debug.Assert(False, "Unable to find control " & ControlName)
Return ""
Else
Return lnk.NavigateUrl
End If
End Function
Public Shared Sub SetTargetBlankIfRequired(ByVal item As System.Web.UI.WebControls.DataGridItem, ByVal ControlName As String, ByVal bTargetBlank As Boolean)
Dim lnk As HyperLink = CType(item.FindControl(ControlName), HyperLink)
SetTargetBlankIfRequired(lnk, bTargetBlank)
End Sub
Public Shared Sub SetTargetBlankIfRequired(ByVal link As HyperLink, ByVal bTargetBlank As Boolean)
If IsNothing(link) Then Return
If True = bTargetBlank Then
link.Attributes.Remove("target") ' //clear old target if any
link.Attributes.Add("target", "_blank")
End If
End Sub
'To Clear all data-entry controls (TextBox or CheckBox) iterative to children /?,ComboBox
Public Shared Function ClearAllEditControls(ByVal container As System.Web.UI.Control) As Boolean
Dim ctrl As Control, tBox As TextBox, chkBox As CheckBox
For Each ctrl In container.Controls
If TypeOf ctrl Is TextBox Then
tBox = CType(ctrl, TextBox)
tBox.Text = ""
ElseIf TypeOf ctrl Is CheckBox Then
chkBox = CType(ctrl, CheckBox)
chkBox.Checked = False
ElseIf Not (ctrl.Controls Is Nothing) Then
ClearAllEditControls(ctrl)
End If
Next
End Function
'call FindPageForm(me), where me is a page
'http://groups.google.com.au/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=uxbuSlKfDHA.3216%40tk2msftngp13.phx.gbl
' recurse controls, favoring NOT to dive deep before finding the HtmlForm
Public Shared Function FindPageForm(ByVal parent As Control) As System.Web.UI.HtmlControls.HtmlForm
Dim current As Control
For Each current In parent.Controls
If TypeOf (current) Is HtmlForm Then
Return CType(current, HtmlForm)
End If
Next
For Each current In parent.Controls
Dim f As HtmlForm = FindPageForm(current)
If Not f Is Nothing Then
Return f
End If
Next
Return Nothing
End Function
Public Shared Function FindControlAddAttribute(ByVal parent As Control, ByVal sControlName As String, _
ByVal AttributeKey As String, ByVal AttributeValue As String) As Boolean
' Dim current As Control
Dim bRet As Boolean = False
Dim ctrl As Control
ctrl = CType(parent.FindControl(sControlName), Button)
If Not IsNothing(ctrl) Then
If TypeOf ctrl Is WebControl Then
Dim webCtrl As WebControl = ctrl
webCtrl.Attributes.Add(AttributeKey, AttributeValue)
bRet = True
Else
Debug.Assert(" Not implemented")
End If
End If
Return bRet
End Function
'Globally Replace "Response.Redirect(" with "WebFormsHelper.SmartRedirect(Page,"
'I've noticed(not confirmed that it happened always) that browser doesn't refreshed URL in address bar(?)
Public Shared Sub SmartRedirect(ByVal p As Page, ByVal url As String)
'Smartnavigation breaks Response.Redirect see http://dotnetjunkies.com/WebLog/petergekko/archive/2003/09/15/1609.aspx
'Obsolete p.SmartNavigation = False
Dim resp As HttpResponse = p.Response
'TODO try to re-code Response.Redirect(ByVal url As String, ByVal endResponse As Boolean) to ensure that it works correctly
'Dim page1 As Page = TryCast(Me._context.Handler, Page)
'If (((Not page1 Is Nothing) AndAlso page1.IsPostBack) AndAlso page1.SmartNavigation) Then
p.Response.Redirect(url)
End Sub
'e.g RadioButtonList
Public Shared Function GetSelectedItemValue(ByVal ctrl As ListControl, ByVal sDefault As String) As String
'If by some reason no item is selected(not sure how it happened????), default should be used
'TODO:? it seems that SelectedValue is better than SelectedItem.Value
Dim sRet As String
If ctrl Is Nothing Then
DebugHelper.TracedLine(" ctrl Is Nothing ")
sRet = sDefault
Else
If ctrl.SelectedItem Is Nothing Then
sRet = sDefault
Else
sRet = CInt(ctrl.SelectedItem.Value)
End If
End If
Return sRet
End Function
'22/5/2006
Public Shared Function SelectedItemsValuesAsCommaSeparatedList(ByVal ctrl As ListControl) As String
Dim sRet As String = ""
If ctrl Is Nothing Then
DebugHelper.TracedLine(" ctrl Is Nothing ")
Else
Dim li As ListItem
Dim sb As New StringBuilder()
For Each li In ctrl.Items
If li.Selected = True Then
sb.AppendFormat("{0},", li.Value)
End If
Next
sRet = StringHelper.LeftBeforeLast(sb.ToString(), ",")
End If
Return sRet
End Function
'TODO Create overload to add value, if not exists
Public Shared Sub SetSelectedValue(ByVal ctrl As ListControl, ByVal value As String, ByVal sDefault As String) 'As String
'From http://groups.google.com.au/group/microsoft.public.dotnet.framework.aspnet/msg/031390d64b55db17?hl=en
' Settings "SelectedValue" will select another item in the DropDownList
'while "SelectedItem.Value" will change the value of the currently selected item.
Try
ctrl.SelectedValue = value
Catch ex As Exception
Try
ctrl.SelectedValue = sDefault
Catch exDef As Exception
ctrl.SelectedValue = ""
End Try
End Try
End Sub
'26/10/2005
Public Shared Function AddTextAndValue(ByVal ctrl As ListControl, ByVal text As String) As ListItem
'The MS ipplementation ListItemCollection.Add Method (String) assignes null to value
Dim li As New ListItem(text, text)
ctrl.Items.Add(li)
Return li
End Function
End Class