Solved

Access dinamically created controls in DataGrid after Button Click

Posted on 2004-09-21
12
299 Views
Last Modified: 2012-05-05
Hello!

I have a DataGrid where users type in values or check checboxes. Every row of DataGrid has editing controls. Editing controls are added with dinamicaly created columns like this:

// Percentage column
tc = new TemplateColumn ();
tc.HeaderText = "Percent";
tc.ItemTemplate = new PercentageItemTemplate ();
tc.ItemStyle.HorizontalAlign = HorizontalAlign.Right;
tc.ItemStyle.CssClass = "text";
detailGrid.Columns.Add (tc);

// CheckBox column
tc = new TemplateColumn ();
tc.HeaderText = "Choose";
tc.ItemTemplate = new CheckboxItemTemplate ();
tc.ItemStyle.HorizontalAlign = HorizontalAlign.Left;
tc.ItemStyle.CssClass = "text";
detailGrid.Columns.Add (tc);

I put a Save button on the page. Event handler for this button should iterate through all rows in DataGrid.

foreach (DataGridItem item in detailGrid.Items)
{
  // do whatever you have to do with data written in DataGrid
}

The problem is that after I click Save button all values are gone. Bound columns which are defined in <asp:datagrid> tag stay in DataGrid also after the page is reloaded (Save button is clicked). All values and columns that are added programatically are gone. I also tried to declare TemplateColumn in <asp:datragrid> tag. Then I set ItemTemplate and other properties in program. The result was empty TemplateColumn. Again were all programatically altered values gone.

Should I add those values to StateBag? How?

Marko
0
Comment
Question by:marko020397
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 3
  • 2
  • +1
12 Comments
 
LVL 28

Expert Comment

by:mmarinov
ID: 12111972
Hi,

when you create dynamically controls they are not included in the view state and when you submit the page the asp.net can not get them from viewstate to show them to to the user

the best practise is to recreate every time the dynamically created controls

other way is to add the dyncamically controls in the init event of the page - then they will be included in the view state and everything will work as you expected

Regards,
B..M
0
 
LVL 25

Expert Comment

by:nauman_ahmed
ID: 12111977
make sure to bind your datagrid in the following way:

if (!Page.IsPostBack)
{
  BindDataGrid();
}

After that you can access the selected dynamic control state easily.

HTH, Nauman.
0
 
LVL 4

Author Comment

by:marko020397
ID: 12112021
I am binding DataGrid the first time the page is loaded just like you wrote. When the page is reloaded (when I click "Save"), DataGrid is empty and I can't fill values with BindDataGrid because all values user has written will be lost.

Maybe I was not exact enough. The page is fine when it is loaded for the first time and all the data are ok. The problem is handling events. All dinamically added collumns are gone after reload/event handling.

Marko
0
PeopleSoft Has Never Been Easier

PeopleSoft Adoption Made Smooth & Simple!

On-The-Job Training Is made Intuitive & Easy With WalkMe's On-Screen Guidance Tool.  Claim Your Free WalkMe Account Now

 
LVL 4

Author Comment

by:marko020397
ID: 12112072
mmarinov,

I can easily recreate dinamically created controls but all the values the user has written in are lost. How can I get the values the user has written in.

The second option you proposed is to add them in to Init event. How can I do this? Will I be able to get the values written by user?
0
 
LVL 17

Expert Comment

by:AerosSaga
ID: 12112099
You will need to rebind after you update your datasource for your recreated dynamically created controls to reflect this update.

Regards,

Aeros
0
 
LVL 28

Expert Comment

by:mmarinov
ID: 12112153
if you choose the first scenario ( to recreate them ) then you will have to remove if (!IsPostBack) and create them on every visit
then the values will no be lost

for the second scenario take a look at this : http://support.microsoft.com/default.aspx?scid=kb;EN-US;317515

Regards,
B..M
0
 
LVL 25

Accepted Solution

by:
nauman_ahmed earned 500 total points
ID: 12112198
marko,

Why you have to create datagrid column on runtime? Why not use a TemplateColumn in the datagrid and add the controls programatically? In my application, I can add and retrieve the values from the HTML Controls. Have a look at the following tutorial:

http://www.c-sharpcorner.com/Code/2003/Jan/AccessDataGridVal.asp

Best, Nauman.
0
 
LVL 4

Author Comment

by:marko020397
ID: 12112969
AerosSaga,

I will rebind the DataGrid after I update my data source. But how can I update my data source? I have no information what did user type in the DataGrid.
0
 
LVL 4

Author Comment

by:marko020397
ID: 12112997
nauman ahmed,

I have also found the example you are offering me. Take a look at the source code in the question. Template column I need can not be made with Templatecolumn in asp:datagrid because it has special class defined in ItemTemplate property.
0
 
LVL 17

Expert Comment

by:AerosSaga
ID: 12113039
Heres my routine to accomplish this bear in mind mine are bound columns so you may need to make a few adjustments but you 'll get the underlying logic:

 Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        If Not IsPostBack Then
            Me.lblProductID.Text = CStr(Session("ProductID")).ToString
            Me.lblQuantity.Text = CInt(Session("Quantity")).ToString
            Me.lblSessionID.Text = CInt(Session("SessionID")).ToString
            Me.lblWeight.Text = CStr(Session("Weight"))
            Session("SessionID") = Me.lblSessionID.Text.ToString
            GetSelectedProductInfo()
            LoadProductData()
            CalculateTotal()
        End If
    End Sub
    Private Sub LoadProductData()
        Dim cnn As New OleDb.OleDbConnection(ConfigurationSettings.AppSettings("SiteDB"))
        Dim cmd As New OleDb.OleDbCommand
        cmd.CommandType = CommandType.Text
        cmd.CommandText = "SELECT TempSession.SessionID, TempSession.SessionString, TempSession.ProductID, TempSession.ProductName,TempSession.ProductPrice, TempSession.Quantity FROM TempSession " & _
                "WHERE SessionString = '" & Me.Session.SessionID & "'"
        cmd.Connection = cnn
        cnn.Open()
        dg.DataSource = cmd.ExecuteReader
        dg.DataBind()
        Me.HyperLink1.NavigateUrl = "ProductDetails.aspx?pid=" & lblProductID.Text.ToString
        Me.HyperLink1.Text = "Continue Shopping"
        Me.HyperLink2.NavigateUrl = "Checkout.aspx?SID=" & Me.Session.SessionID
        Me.HyperLink2.Text = "Proceed To Checkout"
        cnn.Close()
        cmd.Dispose()
        cnn.Dispose()
    End Sub
    Private Sub CalculateTotal()
        Dim cnn As New OleDb.OleDbConnection(ConfigurationSettings.AppSettings("SiteDB"))
        Dim cmd As New OleDb.OleDbCommand
        Dim dr As OleDb.OleDbDataReader
        Dim intQuantity As Integer
        Dim decPrice, decTotal, decTotalTemp As Decimal
        decTotal = 0
        cmd.CommandType = CommandType.Text
        cmd.CommandText = "SELECT * FROM TempSession WHERE SessionString = '" & Me.Session.SessionID.ToString & "';"
        cmd.Connection = cnn
        cnn.Open()
        dr = cmd.ExecuteReader(CommandBehavior.CloseConnection)
        While dr.Read()
            decPrice = CDec(dr.Item("ProductPrice"))
            intQuantity = CInt(dr.Item("Quantity"))
            decTotalTemp = decPrice * intQuantity
            decTotal = decTotalTemp + decTotal
        End While
        Me.lblOrderTotal.Text = CStr(decTotal).ToString
    End Sub
    Private Sub dg_DeleteCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) Handles dg.DeleteCommand
        Dim cnn As New OleDb.OleDbConnection(ConfigurationSettings.AppSettings("SiteDB"))
        Dim cmd As New OleDb.OleDbCommand
        cmd.CommandType = CommandType.Text
        cmd.CommandText = "DELETE * FROM TempSession WHERE ProductID = " & e.Item.Cells(5).Text & " AND SessionString = '" & Me.Session.SessionID & "'"
        cmd.Connection = cnn
        cnn.Open()
        cmd.ExecuteNonQuery()
        cnn.Close()
        cmd.Dispose()
        cnn.Dispose()
        LoadProductData()
        CalculateTotal()
    End Sub
    Private Sub dg_EditCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) Handles dg.EditCommand
        dg.EditItemIndex = e.Item.ItemIndex
        LoadProductData()
        CalculateTotal()
    End Sub
    Private Sub dg_UpdateCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) Handles dg.UpdateCommand
        Dim cnn As New OleDb.OleDbConnection(ConfigurationSettings.AppSettings("SiteDB"))
        Dim cmd As New OleDb.OleDbCommand
        Dim intQuantity As String = CType(e.Item.Cells(3).Controls(0), TextBox).Text
        cmd.CommandType = CommandType.Text
        cmd.CommandText = "UPDATE TempSession SET Quantity = " & intQuantity.ToString & " WHERE SessionString LIKE '" & Me.Session.SessionID.ToString & "' AND ProductName LIKE '" & e.Item.Cells(2).Text & "'"
        cmd.Connection = cnn
        cnn.Open()
        cmd.ExecuteNonQuery()
        cnn.Close()
        cmd.Dispose()
        cnn.Dispose()
        dg.EditItemIndex = -1
        LoadProductData()
        CalculateTotal()
    End Sub
    Private Sub dg_CancelCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataGridCommandEventArgs) Handles dg.CancelCommand
        dg.EditItemIndex = -1
        LoadProductData()
        CalculateTotal()
    End Sub
    Private Sub GetSelectedProductInfo()
        Dim ProductID As String = Request.QueryString("ProductID")
        Dim cnn As New OleDb.OleDbConnection(ConfigurationSettings.AppSettings("SiteDB"))
        Dim cmd As New OleDb.OleDbCommand
        Dim dr As OleDb.OleDbDataReader
        cmd.CommandType = CommandType.Text
        cmd.CommandText = "SELECT * FROM Products WHERE ProductID = " & Me.lblProductID.Text
        cmd.Connection = cnn
        cnn.Open()
        dr = cmd.ExecuteReader(CommandBehavior.CloseConnection)
        While dr.Read
            Session("ProductID") = ProductID
            Session("Name") = dr.Item("Name")
            Session("Price") = dr.Item("Price")
            Session("Weight") = dr.Item("Weight")
        End While
        dr.Close()
        cmd.Dispose()
        cnn.Close()
        cnn.Dispose()
    End Sub

0
 
LVL 4

Author Comment

by:marko020397
ID: 12120205
I have also found the nauman ahmeds example from www.c-sharpcorner.com before I was looking the solution on EE. Although the solution he proposed was not realy the right one, he gave me a clue and made me think. Finaly I realized I can do the same job with controls put on ASPX page and not created programaticaly.

As soon as the control is made programaticaly it doesn't transfer the values on submit. Here was nauman wrong when he suggested to make TemplateColumn and create contorols programaticaly.
0
 
LVL 25

Expert Comment

by:nauman_ahmed
ID: 12123240
Thanks marko that I was able to help you somehow :) Is it possible that you can write the approach you have selected so that members can refer to it in future?

Best, Nauman.
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

One of the pain points with developing AJAX, JavaScript, JQuery, and other client-side behaviors is that JavaScript doesn’t allow for cross domain request for pulling content. For example, JavaScript code on www.johnchapman.name could not pull conte…
Introduction This article shows how to use the open source plupload control to upload multiple images. The images are resized on the client side before uploading and the upload is done in chunks. Background I had to provide a way for user…
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an antispam), the admini…

739 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