• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1097
  • Last Modified:

Dynamic Gridview - ITemplate bound dropdownlist

I am building a dynamic gridview, and adding a bound dropdownlist to each column header.
This works perfectly.  However, I cannot find the dropdownlist values, after a postback.  I build the
gridview with one button, and find the information after another button.  I have
searched everywhere, and I cannot find a solution that fits.  How do I find the selected values from the
drop down lists in the dynamic gridview?

Here is the important code:
'Parse the text file into lines and columns.
    'Load into dataset, and bind to column mapping datagrid
    Protected Sub ProcessImportFile(ByVal ImportFilePath As String, ByVal FileDelimeter As String)

        'The DataSet to Return
        Dim result As New DataSet()

        Dim File As String = ImportFilePath
        Dim delimiter As String = FileDelimeter
        Dim TableName As New DataTable
        Dim i As Integer = 0

        'Open the file in a stream reader.
        Dim s As New StreamReader(File)

        'Split the first line into the columns      
        Dim columns As String() = s.ReadLine().Split(delimiter.ToCharArray())

        'Add the new DataTable to the RecordSet

        For Each col As String In columns
            result.Tables(0).Columns.Add("Column" & i)
            i += 1

        'Read all of the data in the file.        
        Dim AllData As String = s.ReadToEnd()

        'Split off each row at the Carriage Return/Line Feed
        'Default line ending in most windows exports.  
        'You may have to edit this to match your particular file.
        'This will work for Excel, Access, etc. default exports.
        Dim rows As String() = AllData.Split(vbCr & vbLf.ToCharArray())

        'Now add each row to the DataSet        
        For Each r As String In rows
            'Split the row at the delimiter.
            Dim items As String() = r.Split(delimiter.ToCharArray())

            'Add the item


    End Sub

    'Creates the Column Mapping gridview
    Protected Sub CreateGridView(ByVal TheDataSet As DataSet)
        Dim i As Integer = 0
        Dim ds As New DataSet()
        ds = TheDataSet
        Dim strAppName As String = Me.ddlApplications.SelectedValue.ToString
        Dim strClientID As String = Nothing
        If ds.Tables(i).Rows.Count > 0 Then
            Dim gvColumnMapping As New GridView()
            gvColumnMapping.ID = "gvColumnMapping"
            gvColumnMapping.Width = Unit.Pixel(700)
            gvColumnMapping.BorderWidth = Unit.Pixel(0)
            gvColumnMapping.AutoGenerateColumns = False
            gvColumnMapping.ShowFooter = True

            For e As Integer = 0 To ds.Tables(0).Columns.Count - 1
                Dim tf As TemplateField = Nothing

                tf = New TemplateField()
                tf.HeaderTemplate = New DynamicGridViewTextTemplate(ds.Tables(i).Columns(e).ColumnName.ToString, strAppName, DataControlRowType.Header)
                tf.ItemTemplate = New DynamicGridViewTextTemplate(ds.Tables(i).Columns(e).ColumnName.ToString, strAppName, DataControlRowType.DataRow)
                tf.FooterTemplate = New DynamicGridViewTextTemplate(DataControlRowType.Footer, strAppName, ds.Tables(0).Rows.Count)

                'strClientID = gvColumnMapping.FindControl("Column" & e).ClientID

            'AddHandler gvColumnMapping.RowDataBound, New GridViewRowEventHandler(AddressOf Me.DynamicGrid_RowDataBound)
            'AddHandler gvColumnMapping.Init, New EventHandler(AddressOf Me.gvColumnMapping_Init)

            gvColumnMapping.DataSource = ds.Tables(0)
        End If

    End Sub

    'Protected Sub DynamicGrid_RowDataBound(ByVal sender As Object, ByVal e As GridViewRowEventArgs)
    '    If e.Row.RowType = DataControlRowType.Footer Then
    '    End If
    'End Sub

    'Get the import file path and delimeter
    'And call processimportfile, so the column mapping gridview can be created
    Protected Sub btnLoadColumnMapping_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnLoadColumnMapping.Click
        Dim strImportFilePath As String
        Dim strDelimeter As String
        strImportFilePath = Me.fuImportFile.PostedFile.FileName
        Me.lblFileUploadFile.Text = strImportFilePath
        strDelimeter = ","
        ProcessImportFile(strImportFilePath, strDelimeter)

    End Sub

End Class

Public Class DynamicGridViewTextTemplate
    Implements ITemplate
    Private _ColName As String
    Private _rowType As DataControlRowType
    Private _Count As Integer
    Private _AppName As String

    Public Sub New(ByVal ColName As String, ByVal AppName As String, ByVal RowType As DataControlRowType)
        _ColName = ColName
        _rowType = RowType
        _AppName = AppName
    End Sub
    Public Sub New(ByVal RowType As DataControlRowType, ByVal ArticleCount As Integer)
        _rowType = RowType
        _Count = ArticleCount
    End Sub
    Public Sub InstantiateIn(ByVal container As System.Web.UI.Control) Implements ITemplate.InstantiateIn
        Select Case _rowType
            Case DataControlRowType.Header
                Dim ddl As New DropDownList()
                ddl.ID = _ColName
                AddHandler ddl.DataBinding, New EventHandler(AddressOf Me.ddl_DataBind)
                Exit Select
            Case DataControlRowType.DataRow
                Dim lbl As New Label()
                AddHandler lbl.DataBinding, New EventHandler(AddressOf Me.lbl_DataBind)
                Exit Select
            Case DataControlRowType.Footer
                Dim flc As New Literal()
                flc.Text = "<b>Total No Items" & _Count & "</b>"
                Exit Select
            Case Else
                Exit Select
        End Select
    End Sub

    Private Sub lbl_DataBind(ByVal sender As [Object], ByVal e As EventArgs)
        Dim lbl As Label = DirectCast(sender, Label)
        Dim row As GridViewRow = DirectCast(lbl.NamingContainer, GridViewRow)
        lbl.Text = DataBinder.Eval(row.DataItem, _ColName).ToString()
    End Sub

    Private Sub ddl_DataBind(ByVal sender As [Object], ByVal e As EventArgs)
        Dim ddl As DropDownList = DirectCast(sender, DropDownList)
        Dim row As GridViewRow = DirectCast(ddl.NamingContainer, GridViewRow)
        Dim ds As New DataSet
        ds = SelectAllAttributeNames()
        ddl.DataSource = ds.Tables(0)
        ddl.DataTextField = ds.Tables(0).Columns(0).ColumnName.ToString
        ddl.DataValueField = ds.Tables(0).Columns(0).ColumnName.ToString
    End Sub

    Private Function SelectAllAttributeNames() As DataSet
        Dim ds As New DataSet
        Dim cbApplication As New cBApplication
        cbApplication.AppName = _AppName
        ds = cbApplication.SelectAllAssignedAttributes()
        Return ds
    End Function
2 Solutions
try this :-

 Dim ddl1 As DropDownList = CType(GridView1.HeaderRow.FindControl("ddl1"), DropDownList)

Open in new window

frontback45Author Commented:
I  put this in the second button click event, and I receive the following error:

Object reference not set to an instance of an object.
Do you understand how dynamic controls work in asp.net?  They aren't persisted, so when the page posts back, you have to recreate them just like they were or they will disappear.  I don't ever recommend their usage unless they are absolutely needed.


There is still the Request.Form collection, and while I don't normally recommend it's usage, if you just need a single value they changed, and you know where they changed it, you can use Request.Form("MyControlUniqueID").  You'll still have to rebuild the gridview to update according to the change, but it can save you a ton of time.
Cloud Class® Course: Amazon Web Services - Basic

Are you thinking about creating an Amazon Web Services account for your business? Not sure where to start? In this course you’ll get an overview of the history of AWS and take a tour of their user interface.

you need to bind data to the dropdown list in RowDataBound event of the gridview when your page was posted back.

frontback45Author Commented:
Thanks for all responses.  Since there is not a good solution for this issue, I am going to try a different approach.  Just an FYI to anyone else looking at this issue... MSDN provided this approach, but failed to mention there is not a "good" way to get values from the gridview, after post-back.  I am going to split the points.
frontback45Author Commented:
I wish someone would have offererd an alternative approach.
For an alternative, typically I use asp:repeaters nested within each other to draw the table as required, that way I don't have to worry about recreating controls again on postback.  You don't get all the fancy features of the gridview, and it gets confusing in it's own way.

You could also use a custom control which is more like you were doing, you just embed all the dynamic nature into the control, which automatically will recreate controls on a postback, but this has a steep learning curve if you are unfamiliar with this process.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now