Click here to Skip to main content
Click here to Skip to main content

ASP.NET DataGrid storing both original and edited values

By , 3 May 2007
Rate this:
Please Sign up or sign in to vote.

Introduction

The "normal" use of a web DataGrid with regards to data editing and update assumes the following sequence: the user selects the row which is to be edited, the row is transformed for editing (e.g., labels become textboxes etc.), values are changed, the Update button is pressed, data is written to the original data source (e.g., database), the grid is rebound, and the new values for the given row appear.

However, we might want to update a number of rows and commit all changes at once. In addition, the user may want to have both the original and the edited values stored in the same grid while having the edited ones appear only on item edit command.

This piece of code also solves the problem of copying columns within the same table or between various tables.

Using the code

This code is for those who have spent some time with the ASP DataGrid - you will understand where to put the code. One of the important things is not to forget to properly configure the DataGrid with regards to its column items, controls, bindings etc. Also, while the code presented below is quite flexible, it is still limited; therefore, we have to make some changes in the design. However, if you are willing to implement the ideas presented here and build a fully flexible MegaGrid control, welcome.

<!--Here is a set of columns for the datagrid.
NOTE: The EditItemTemplate CONTROLS in our case its textboxes
1. are named as "edit" and a number - this consistant naming will be used in the code
2. are bound to the field which is the same as the Regular item template is bound to
   but with "_2" at the end.
'Please read through the code behind comments in order to understand why...-->

<Columns>
    <asp:TemplateColumn HeaderText="Line">
        <ItemTemplate>
            <asp:Label id=label1 runat="server" 
              text='<%# DataBinder.Eval(Container.DataItem, "value_A") %>'>
            </asp:Label>
        </ItemTemplate>
        <EditItemTemplate>
            <asp:TextBox id=edit1 runat="server" 
              text='<%# DataBinder.Eval(Container.DataItem, "value_A_2") %>'>
            </asp:TextBox>
        </EditItemTemplate>
    </asp:TemplateColumn>
    <asp:TemplateColumn HeaderText="Rem Qty/Cr">
        <ItemTemplate>
            <asp:Label id=Label2 runat="server" 
              text='<%# DataBinder.Eval(Container.DataItem, "value_B") %>'>
            </asp:Label>
        </ItemTemplate>
        <EditItemTemplate>
            <asp:TextBox id=e1 runat="server" 
              text='<%# DataBinder.Eval(Container.DataItem, "value_B_2") %>'>
            </asp:TextBox>
        </EditItemTemplate>
    </asp:TemplateColumn>
</Columns>

Here is the code-behind:

Public Sub BindGrid(ByVal dt As DataTable)
    'get a populated datatable into this sub
     
    'Duplicate columns in the datatable: 
     dt = DataTableX2(dt, "_2")
     'look below for the details of the table duplication
     dgrDetails.DataSource = dt
     dgrDetails.DataBind()

End Sub

Function DataTableX2(ByVal name As DataTable, _
         ByVal new_column_suffix As String) As DataTable
    'this function receives a Datatable and 
    'a SUFFIX string which will be appended to the
    'Column Names of the duplicate columns in the returned table. 
    'E. G.: Original table: "ColA", "ColB" | 
    '  Returned table: "ColA", "ColB",
    '  "ColA_2", "ColB_2".

    'will keep track of the original number of columns in the datatable
    Dim c As Integer
    Dim i As Integer 'counter-runned for the loops

    'store the original number of columns: 
    c = name.Columns.Count

    'go through all of the original columns and add the 
    'same number of columns with the same name, followed by the suffix:
    For i = 0 To c - 1
        'create new column: 
        Dim new_column As New DataColumn
        'get the name from the original column and append the suffix:
        new_column.ColumnName = _
          name.Columns(i).ColumnName & new_column_suffix
        'add the newly created column to the collection: 
        name.Columns.Add(new_column)
    Next i

    'go through all of the rows in the datatable and copy 
    'the values of the original cells to the newly created ones: 
    Dim r As DataRow
    For Each r In name.Rows
        For i = 0 To c - 1
            r.Item(i + c) = r.Item(i)
        Next i
    Next r

    'return the table with double the columns where the duplicates
    'have the same name as original columns plus the suffix.
    Return name

End Function
  
'the following happens when user presses 
'"Update" in the row which is being edited:
Private Sub dgrDetails_UpdateCommand(ByVal source As Object, _
        ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) _
        Handles dgrDetails.UpdateCommand

    'perfom datasource update: 
    Me.dgrDetails.DataSource = UpdatedTable(e, _
      CType(Session("Data_Source1"), DataTable), 3)
    'look below for more details on this
    'set the editing index to nathing: 
    Me.dgrDetails.EditItemIndex = -1
    'refresh the look: 
    Me.DataBind()

End Sub

Function UpdatedTable(ByVal e As _
         System.Web.UI.WebControls.DataGridCommandEventArgs, _
         ByVal Data_Source As DataTable, _
         ByVal LeftOffset As Integer) As DataTable
    'accepts the e - the datagrid selected item, datatable 
    'with original values, and number of columns (e.g. command etc.)
    'you have put in front of the bound columns - -LeftOffset.

    Dim i As Integer 'runner for the loop

    'go through all of the cells in the selected row of the datagrid
    'and update corresponding items in the datatable
    'note that datatable columns we go through start in the middle 
    'because we are updating the "duplicate" columns
    'which are there to store edited values. 
    'thus we are leaving the original values intact. 
    'in order to bring up the from the detagrid value we refer to the cell, 
    'find a textbox there with the name "edit" + i +1. 
    'In the edit item template we have named our textboxes edit1, edit2, edit3... 
    'where the number corresponds to the ordinal 
    'of the bound column - the number of the preceeding non bound columns
    'then we cast this control into a texbox (we know that this 
    'is a textbox) and assign its .Text value to the DataTable's item... 

    For i = 0 To dgrDetails.Columns.Count - 1 - LeftOffset
        Data_Source.Rows(e.Item.ItemIndex).Item(i + CInt(Data_Source.Columns.Count / 2)) = _
          CType(dgrDetails.Items(e.Item.ItemIndex).Cells(i + _
          LeftOffset).FindControl("edit" + _
          (i + 1).ToString), Web.UI.WebControls.TextBox).Text
    Next i

    Return Data_Source

End Function

Points of interest

Duplicating datatable columns as well as implementing common naming for bound datagrid controls are two things which will help me a lot in the future. Also, the whole idea of having virtually two datasources for the same datagrid is quite interesting.

History

  • Later.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Alexei Fimine
Software Developer
Canada Canada
"And though I have the gift of prophecy, and understand all mysteries, and all knowledge; and though I have all faith, so that I could remove mountains, and have not charity, I am nothing. And though I bestow all my goods to feed the poor, and though I give my body to be burned, and have not charity, it profiteth me nothing. Charity suffereth long, and is kind; charity envieth not; charity vaunteth not itself, is not puffed up, Doth not behave itself unseemly, seeketh not her own, is not easily provoked, thinketh no evil; Rejoiceth not in iniquity, but rejoiceth in the truth; Beareth all things, believeth all things, hopeth all things, endureth all things."

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Mobile
Web01 | 2.8.140415.2 | Last Updated 3 May 2007
Article Copyright 2007 by Alexei Fimine
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid