Tuesday, June 30, 2009

Custom Link In Gridview

One control I try to use as much as possible is the Gridview. Quick, simple and customizable, for it's purpose, to the 'T'. I do wish that the Gridview allowed more customization in the area of display. Several times I've a display that required full width column spans throughout the table for some reason and I've had to resort to building my own HTML and injecting it into a div or literal control. But, when I can, I use the Gridview.

One hold back is that the Gridview has the command buttons, which is Update, Delete, etc, but only if tied to a data source object, which I'm not sure if anyone uses. I often find that I need to put in a "View" linkbutton. But how do we capture the linkbutton postback and then tie that to the correct ID of the row and execute what we need to?

Let's say we have a program that develops tests and we have a Gridview that displays a list of all tests: Name (bound), Date Created (bound), View (item template > link button). Let's name the View linkbutton lnkView for convention-sake. If there's one thing that good security calls for it's almost NEVER showing database IDs. Just not a good idea. So, where do we store the test's ID that we want to view for each row? Easy, in the link button. You can do the following to rename each lnkView to hold the ID of the given test of that row, given that ds is a DataSet holding your data from the database:

Protected Sub GridView1_DataBound(ByVal sender As Object, ByVal e As System.EventArgs) Handles GridView1.DataBound
Dim rowIndex As Integer = 0
For Each gvr As GridViewRow In GridView1.Rows
Dim lnk As LinkButton = CType(gvr.FindControl("lnkView"), LinkButton)
lnk.ID = "lnkView" + ds.Tables(0).Rows(rowIndex)("ID").ToString
rowIndex += 1
Next
End Sub

Now that all of your lnkViews have been renamed, you can now capture it when a user clicks on it. In the page load event, wrapped in a IsPostBack If statement, you can enter this to determine if the lnkView has been clicked and grab the ID of the test that it corresponds to:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If IsPostBack Then
If Request("__EVENTTARGET").ToString.Contains("lnkView") Then
Dim TestID As Integer = CInt(Replace(Request("__EVENTTARGET").ToString, "lnkView", ""))
End If
End If
End Sub

We kept "lnkView" in the lnkView's ID so we can easily decide if the postback target is the link button we're looking for. The Request("__EVENTTARGET") grabs the ID of the control that caused the postback, in this case the lnkView linkbutton. The Request might return the ClientID so it might looks something like:

ctl00$GridView1$ctl02$lnkView181

but you can just parse it.

1 comment:

Meg said...

i must say, i'm happy that you're blogging about something you like, but i miss being able to understand it. :(