Insert using a gridview with AutoGenerateColumns="true"

Hi all,

Here is my problem. I'm trying to create a dynamic gridView that can be connected to différents DataSources. To do that, I setted the AutoGenerateColumns to true and I used some command field for the delete and the edit.
Everything works fine for the update and the delete.

My next step was to manage the insert but it's impossible to have correct fields in the footer. I was thinking that .Net was able to understand that for my insert, I want the same "template" that for the edit but I tried a lot of different methods and nothing works.

Is there a method to automatically fill the footer with the "edit" template and use the automatic insert system of the gridview with AutoGenerateColumns="true" ?

I have no idea what can be in cells so for this part of the application I must auto generate columns. It's mandatory.

Maybe it's possible to copy the "edit" content of data cells to the footer or a tricks like that ?

Here is the code...

(I set the QueryName of the domainDataSource in the page init dynamically)

 
<cc1:DomainDataSource ID="dds" runat="server" 
       DomainServiceTypeName="DomainName" 
 EnableDelete="true" EnableInsert="true" EnableUpdate="true" >
</cc1:DomainDataSource>


<asp:GridView ID="grd" runat="server"
       DataSourceID="dds" AutoGenerateColumns="true"  >
    <Columns>
        <asp:CommandField ShowDeleteButton="True" ShowEditButton="True" />
    </Columns>
</asp:GridView>

Open in new window


Thanks for the answers and I hope I'll find a solution.


------ Edit, solved

Ok, I found a solution but it's a little tricky because GridView doesn't handles Insert commands like the formviews...

So I created controls manually in the gridview creation. But because Insert event is not handled, we need to simulate the insert of the dataSource like for the update...
With a little bit of reflector, I was able to do the insert.

Here is the code that works on my project...

Creation of textbox controls and button

            
            Dim grd As GridView = DirectCast(sender, GridView)
            Dim footer As GridViewRow = grd.FooterRow
            Dim b = New Button()
            b.Text = "Insert"
            b.CommandName = "Insert"
            b.CausesValidation = True
            footer.Cells(0).Controls.Add(b)

            For index As Integer = 1 To footer.Cells.Count - 1

                Dim dcfc As DataControlFieldCell = _

                    TryCast(footer.Cells(index), DataControlFieldCell)

                If dcfc IsNot Nothing Then

                    Dim field As String = dcfc.ContainingField.ToString
                    Dim txt = New TextBox()
                    ColumnNameBinding = field
                    AddHandler txt.DataBinding, AddressOf ControlDataBinding
                    footer.Cells(index).Controls.Add(txt)

                End If

            Next

Open in new window


Method to do the Insert (to raise when the user click on insert button)

      Private Sub HandleInsert(ByVal row As GridViewRow, ByVal rowIndex As Integer, ByVal causesValidation As Boolean)

            If ((Not causesValidation OrElse (Me.Page Is Nothing)) OrElse Me.Page.IsValid) Then

                Dim data As DataSourceView = Nothing

                data = DirectCast(dds, IDataSource).GetView(String.Empty)

                Dim e As New GridViewUpdateEventArgs(rowIndex)

                Dim dataKeyNamesInternal As String() = New String() {"Key of the gridview"}

                Dim includePrimaryKey As Boolean = True

                Dim includeReadOnlyFields As Boolean = False

                'We fill the collection with the data of the gridview.
                'We must use cells because column number is 0 for autogenerateColumns="true"
		'First column is the button
                For i As Integer = 1 To row.Cells.Count - 1

                    Dim dcfc As DataControlFieldCell = TryCast(row.Cells(i), DataControlFieldCell)

                    If dcfc IsNot Nothing Then

                        Dim dictionary As New OrderedDictionary

                        Dim field As String = dcfc.ContainingField.ToString

                        'Dim dictionary As New OrderedDictionary

                        dcfc.ContainingField.ExtractValuesFromCell(dictionary, TryCast(row.Cells.Item(i), DataControlFieldCell), row.RowState, includeReadOnlyFields)

                        Dim entry As DictionaryEntry
                        For Each entry In dictionary

                            If (includePrimaryKey OrElse (System.Array.IndexOf(Of Object)(dataKeyNamesInternal, entry.Key) = -1)) Then

                                e.NewValues.Item(entry.Key) = entry.Value

                            End If
                        Next

                    End If

                Next

                If (Not e.Cancel) Then

                    data.Insert(e.NewValues, New DataSourceViewOperationCallback(AddressOf Me.HandleInsertCallback))

                End If

            End If

        End Sub

Open in new window


And just a callback function HandleInsertCallback used by data.Insert...

It's not perfect but it's working and. I'll see if I have the time to improve the code.

Regards,
Itec_Asked:
Who is Participating?
 
Itec_Connect With a Mentor Author Commented:
Ok, I found a solution but it's a little tricky because GridView doesn't handles Insert commands like the formviews...

So I created controls manually in the gridview creation. But because Insert event is not handled, we need to simulate the insert of the dataSource like for the update...
With a little bit of reflector, I was able to do the insert.

Here is the code that works on my project...

Creation of textbox controls and button

            
            Dim grd As GridView = DirectCast(sender, GridView)
            Dim footer As GridViewRow = grd.FooterRow
            Dim b = New Button()
            b.Text = "Insert"
            b.CommandName = "Insert"
            b.CausesValidation = True
            footer.Cells(0).Controls.Add(b)

            For index As Integer = 1 To footer.Cells.Count - 1

                Dim dcfc As DataControlFieldCell = _

                    TryCast(footer.Cells(index), DataControlFieldCell)

                If dcfc IsNot Nothing Then

                    Dim field As String = dcfc.ContainingField.ToString
                    Dim txt = New TextBox()
                    ColumnNameBinding = field
                    AddHandler txt.DataBinding, AddressOf ControlDataBinding
                    footer.Cells(index).Controls.Add(txt)

                End If

            Next

Open in new window


Method to do the Insert (to raise when the user click on insert button)

      Private Sub HandleInsert(ByVal row As GridViewRow, ByVal rowIndex As Integer, ByVal causesValidation As Boolean)

            If ((Not causesValidation OrElse (Me.Page Is Nothing)) OrElse Me.Page.IsValid) Then

                Dim data As DataSourceView = Nothing

                data = DirectCast(dds, IDataSource).GetView(String.Empty)

                Dim e As New GridViewUpdateEventArgs(rowIndex)

                Dim dataKeyNamesInternal As String() = New String() {"Key of the gridview"}

                Dim includePrimaryKey As Boolean = True

                Dim includeReadOnlyFields As Boolean = False

                'We fill the collection with the data of the gridview.
                'We must use cells because column number is 0 for autogenerateColumns="true"
		'First column is the button
                For i As Integer = 1 To row.Cells.Count - 1

                    Dim dcfc As DataControlFieldCell = TryCast(row.Cells(i), DataControlFieldCell)

                    If dcfc IsNot Nothing Then

                        Dim dictionary As New OrderedDictionary

                        Dim field As String = dcfc.ContainingField.ToString

                        'Dim dictionary As New OrderedDictionary

                        dcfc.ContainingField.ExtractValuesFromCell(dictionary, TryCast(row.Cells.Item(i), DataControlFieldCell), row.RowState, includeReadOnlyFields)

                        Dim entry As DictionaryEntry
                        For Each entry In dictionary

                            If (includePrimaryKey OrElse (System.Array.IndexOf(Of Object)(dataKeyNamesInternal, entry.Key) = -1)) Then

                                e.NewValues.Item(entry.Key) = entry.Value

                            End If
                        Next

                    End If

                Next

                If (Not e.Cancel) Then

                    data.Insert(e.NewValues, New DataSourceViewOperationCallback(AddressOf Me.HandleInsertCallback))

                End If

            End If

        End Sub

Open in new window


And just a callback function HandleInsertCallback used by data.Insert...

It's not perfect but it's working and. I'll see if I have the time to improve the code.

Regards,
0
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.

All Courses

From novice to tech pro — start learning today.