Thursday, December 30, 2010

Wiring up a common click event handler in an ASP.NET page

I was just refactoring a server-side control and ran into some horrible code.  Basicaly there was a big listbox that was supposed to hold people's names with letters A through Z to the left which were ASP.NET LinkButtons.  lnkBtnA, lnkBtnB, etc.  Each link button had its own click handler whose code only differed by the letter that would be used to filter the listbox.  Of course, since I needed to change how the filter worked, I would have had to make 26 edits to each of the subroutines.  Instead, I deleted them all and wrote the following:

Note: RegisterClickEvents() has to be called in the Page_Init event, as Page_Load is too late in the cycle.


Private Sub RegisterClickEvents()
 For Each objControl In Me.Controls
  If TypeOf objControl Is System.Web.UI.WebControls.LinkButton Then
   If InStr(DirectCast(objControl, System.Web.UI.WebControls.LinkButton).ID, "lnkBtn", CompareMethod.Text) > 0 Then
    AddHandler DirectCast(objControl, System.Web.UI.WebControls.LinkButton).Click, AddressOf FilterLinkButtonClick
   End If
  End If
 Next
End Sub



Protected Sub FilterLinkButtonClick(ByVal sender As Object, ByVal e As EventArgs)
 'Find the letter from the ID of the control that was clicked so we know what to filter by
 Dim strFilterLetter As String
 strFilterLetter = Replace(UCase(DirectCast(sender, System.Web.UI.WebControls.LinkButton).ID), "LNKBTN", "")
  
 '... other code to do the filtering on my listbox

End Sub

Wednesday, December 29, 2010

How to tell if a property exists by name

I recently was working on a library to manage reports in an application (probably a good candidate for an open source project) and needed to be able to grab the value of a property on an object by name without knowing if that property existed or not.  Of course .NET reflection comes in handy for doing this, and this is the easy wrapper code I came up with.  Just add this to any class to query for the existence of a property or to retrieve its value as a string.  There's way more you can do with reflection, but this wraps up at least some of the basics.


''' <summary>
''' Indicates if a property exists on this object by name
''' </summary>
''' <param name="PropertyName">The CASE SENSITIVE name of the property on this object</param>

Public Function PropertyExistsByName(ByVal PropertyName As String) As Boolean
    Try
        Return Me.GetType().GetProperty(PropertyName) IsNot Nothing
    Catch ex As Exception
        Return False
    End Try
End Function



''' <summary>
''' Returns the value of a public property on this object by name
''' </summary>
''' <param name="PropertyName">The CASE SENSITIVE name of the property on this object</param>
''' <param name="ReturnIfNotFound">What to return if the property is found not to exist or if there is an error.</param>

Public Function GetPropertyValueByName(ByVal PropertyName As String, Optional ByVal ReturnIfNotFound As String = "") As String
    Try
        If PropertyExistsByName(PropertyName) Then
            Return Me.GetType().GetProperty(PropertyName).GetValue(Me, Nothing).ToString
        Else
            Return ReturnIfNotFound
        End If
    Catch ex As Exception
        Return ReturnIfNotFound
    End Try
End Function