Here’s the situation: I’m getting a dataset from my business layer that contains some core columns that are always the same along with some that are variable depending on the business area being queried. On top of that, the gridview I need to build for the UI has two other columns (checkbox and button). The button fires up a Filenet viewer with context based information in the querystring. All this means that creating the gridview only in the UI designer, or only in code didn’t work terribly well. So this is what I did.
1. teach the business layer method how to parse a comma delimited field into corresponding columns in the dataset:
Dim props As String()
For Each pair As String In enttColl.ElementAt(0).DocPropertyData.Split(";")
props = pair.Split(",")
dt.Columns.Add(props(0), System.Type.GetType("System.String"))
Next
In this For Each loop, I’m parsing out the DocPropertyData to find the individual document properties within. The pattern is “XX,False,YY,True…” where the alpha portion is a code for document property followed by a boolean. There can be zero or many of these (most likely 1 or more). The alpha portion becomes the column header, added to the DataTable I created already based on the first nine fixed columns in the DataSet.
The next step is to create DataRows for each row in the DataSet and assign values to those row items. The first nine items come from the nine fixed columns in the DataSet. The remaining values come from the props array.
Dim index As Integer = 10
If Not props Is Nothing Then
For Each prop In props
row.Item(index) = props(1)
index += 1
Next
End If
Now I can pass the DataSet to my calling code (UI code behind) and see the first nine, plus the variable document property columns.
2. Next step, get all the necessary columns on the UI.
I start out by defining the fixed portion of the GridView on the UI. In code behind, I create a DataTable with matching columns. Then I loop through the DataSet I received from the Business Layer and add the document property columns to the DataTable.
For Each col As DataColumn In dsResult.Tables(0).Columns
If col.Ordinal > 9 Then ' doc prop fields
Dim dfield As BoundField = New BoundField()
dfield.HeaderText = col.ColumnName
dfield.DataField = col.ColumnName
grdResults.Columns.Add(dfield)
dt.Columns.Add(New DataColumn(col.ColumnName, GetType(String))) ' need to count through the props and create
End If
Next
Then I loop through the DataSet and assign values to those columns.
3. wire up the button field in the second column of the GridView
This was frustrating. I started out trying to do this client side, but had issues because the values I need for the query string are not available until the GridView is bound to the DataSet. I need the button click to result in a new browser window opening with the destination page (containing the Filenet viewer) and a querystring of required values.
I described the iterative process of finding a solution in my previous post, My Process… Persistent Hacking. The solution was to add an OnRowCommand event handler.
Protected Sub grdResults_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles grdResults.RowCommand
If (e.CommandName = "ViewDoc") Then
Dim gvr As GridViewRow = DirectCast(DirectCast(e.CommandSource, Button).NamingContainer, GridViewRow)
Dim RowIndex As Integer = gvr.RowIndex
Dim docId As String = grdResults.Rows(RowIndex).Cells(3).Text
ClientScript.RegisterStartupScript(Page.GetType(), "", "window.open('Tabbed.aspx?docID=" + docId + "&userID=username&password=password1&pageNo=1');", True)
End If
End Sub
I’d never worked with ClientScript before and saw a lot of examples that didn’t make sense to me before I found one that did.