Question

Problem

I have a ButtonColumn to edit a row defined like this:

<asp:ButtonColumn DataTextField="job_code" ButtonType="LinkButton" HeaderText="Job Code"
    CommandName="edit"></asp:ButtonColumn>

and in the OnItemCommand handler for the DataGrid I have this code:

If e.CommandName = "edit" Then
    Dim o As ListDataModel = CType(e.Item.DataItem, ListDataModel)
    If o Is Nothing Then
        Exit Sub
    End If

    ...
End If

but e.Item.DataItem is null here.

I've looked through the related questions and verified the following:

  1. The ItemType of e.Item is set to ListItemType.Item and therefore should be allowed to house the DataItem. This also jives with the MSDN documentation.
  2. I leveraged data binding -see the code section below.
  3. I have set the DataKeyField attribute on the asp:DataGrid like this: DataKeyField="job_code".

Data Binding Code (happens in the Search method)

Using reader As SqlDataReader = cmd.ExecuteReader()
    Dim list As List(Of ListDataModel) = New List(Of ListDataModel)

    While reader.Read()
        list.Add(New ListDataModel With
                 {
                     ...
                 })
    End While

    dgSearchResults.DataSource = list
    dgSearchResults.DataBind()
End Using

Now, the Search method is an onserverclick event handler for an input button. The flow would be for the user to search for the results and then click on one of the command button to edit the row, therefore the Search method would not be run when the OnItemCommand handler was fired.

Was it helpful?

Solution

Alright, so the resolution for this ended up a bit convoluted. First I ended up having to store the search result set in Session, so I built a Dictionary for that:

Dim cache As Dictionary(Of String, ListDataModel) = New Dictionary(Of String, ListDataModel)

and added to that Dictionary when building the ListDataModel objects. Then, in the OnItemCommand handler I ended up having the use Reflection like this:

Dim cache As Dictionary(Of String, ListDataModel) = CType(Session("SearchResults"), Dictionary(Of String, ListDataModel))
If cache Is Nothing Then
    Exit Sub
End If

Dim prop As PropertyInfo = e.CommandSource.GetType().GetProperty("Text")
If prop Is Nothing Then
    Exit Sub
End If

Dim o As ListDataModel = cache(prop.GetValue(e.CommandSource, Nothing).ToString())
If o Is Nothing Then
    Exit Sub
End If

As you can see I first pulled the "SearchResults" out of Session, then tried to get at the Text property of the DataGridLinkButton. I had to use Reflection because the DataGridLinkButton class isn't visible. Then finally, if I found the property, I pulled off the value.

Though this works, and I hope that my solution is a by-product of something else weird in the application I'm maintaining, it's really not what I wanted to do in the end. This is a pretty poor interface to the DataGrid -but it is ASP.NET 2.0 and so it's some old stuff!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top