Solved

Dynamic Gridview - ITemplate bound dropdownlist

Posted on 2011-03-06
7
1,061 Views
Last Modified: 2013-11-27
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
        result.Tables.Add(TableName)

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

        '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
            result.Tables(0).Rows.Add(items)
        Next

        CreateGridView(result)

    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)

                gvColumnMapping.Columns.Add(tf)
                'strClientID = gvColumnMapping.FindControl("Column" & e).ClientID
            Next

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

            gvColumnMapping.DataSource = ds.Tables(0)
            gvColumnMapping.DataBind()
            phColumnMapping.Controls.Add(gvColumnMapping)
        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)
                container.Controls.Add(ddl)
                Exit Select
            Case DataControlRowType.DataRow
                Dim lbl As New Label()
                AddHandler lbl.DataBinding, New EventHandler(AddressOf Me.lbl_DataBind)
                container.Controls.Add(lbl)
                Exit Select
            Case DataControlRowType.Footer
                Dim flc As New Literal()
                flc.Text = "<b>Total No Items" & _Count & "</b>"
                container.Controls.Add(flc)
                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
0
Comment
Question by:frontback45
7 Comments
 
LVL 9

Expert Comment

by:mayank_joshi
ID: 35055200
try this :-

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

Open in new window

0
 

Author Comment

by:frontback45
ID: 35058259
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.
0
 
LVL 33

Accepted Solution

by:
raterus earned 250 total points
ID: 35062315
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.

However...

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.
0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
LVL 3

Assisted Solution

by:xiong8086
xiong8086 earned 250 total points
ID: 35080169
you need to bind data to the dropdown list in RowDataBound event of the gridview when your page was posted back.

0
 

Author Comment

by:frontback45
ID: 35084969
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.
0
 

Author Closing Comment

by:frontback45
ID: 35084991
I wish someone would have offererd an alternative approach.
0
 
LVL 33

Expert Comment

by:raterus
ID: 35085175
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.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

      Install BugTracker on Windows 2008 server Step 1:  Install windows 2008 server 32 bit OS and configure IIS. Step 2:  Install SQL server ( SQL server 2005 or SQL server 2005 Express edition. The installer for 2008  version isn’t very f…
Introduction (All good things must come to an end (http://en.wikipedia.org/wiki/All_Good_Things...)) The original MySQL API (http://php.net/manual/en/book.mysql.php) has gone away, deprecated by PHP in Version 5.5, and removed from PHP in all curre…
This video teaches users how to migrate an existing Wordpress website to a new domain.
Wufoo.com provides powerful tools for surveying targeted groups, and utilizing data from completed surveys to find trends, discover areas of demand or customer expectation, and make business decisions on products or services.

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now