marko020397
asked on
Access dinamically created controls in DataGrid after Button Click
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.HorizontalAli gn = HorizontalAlign.Right;
tc.ItemStyle.CssClass = "text";
detailGrid.Columns.Add (tc);
// CheckBox column
tc = new TemplateColumn ();
tc.HeaderText = "Choose";
tc.ItemTemplate = new CheckboxItemTemplate ();
tc.ItemStyle.HorizontalAli gn = 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
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.HorizontalAli
tc.ItemStyle.CssClass = "text";
detailGrid.Columns.Add (tc);
// CheckBox column
tc = new TemplateColumn ();
tc.HeaderText = "Choose";
tc.ItemTemplate = new CheckboxItemTemplate ();
tc.ItemStyle.HorizontalAli
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
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.
if (!Page.IsPostBack)
{
BindDataGrid();
}
After that you can access the selected dynamic control state easily.
HTH, Nauman.
ASKER
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
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
ASKER
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?
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?
You will need to rebind after you update your datasource for your recreated dynamically created controls to reflect this update.
Regards,
Aeros
Regards,
Aeros
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
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
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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.
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.
ASKER
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.
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.
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.ToStr ing
GetSelectedProductInfo()
LoadProductData()
CalculateTotal()
End If
End Sub
Private Sub LoadProductData()
Dim cnn As New OleDb.OleDbConnection(Conf igurationS ettings.Ap pSettings( "SiteDB"))
Dim cmd As New OleDb.OleDbCommand
cmd.CommandType = CommandType.Text
cmd.CommandText = "SELECT TempSession.SessionID, TempSession.SessionString, TempSession.ProductID, TempSession.ProductName,Te mpSession. ProductPri ce, 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(Conf igurationS ettings.Ap pSettings( "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.ToStr ing & "';"
cmd.Connection = cnn
cnn.Open()
dr = cmd.ExecuteReader(CommandB ehavior.Cl oseConnect ion)
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. DataGridCo mmandEvent Args) Handles dg.DeleteCommand
Dim cnn As New OleDb.OleDbConnection(Conf igurationS ettings.Ap pSettings( "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. DataGridCo mmandEvent Args) 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. DataGridCo mmandEvent Args) Handles dg.UpdateCommand
Dim cnn As New OleDb.OleDbConnection(Conf igurationS ettings.Ap pSettings( "SiteDB"))
Dim cmd As New OleDb.OleDbCommand
Dim intQuantity As String = CType(e.Item.Cells(3).Cont rols(0), TextBox).Text
cmd.CommandType = CommandType.Text
cmd.CommandText = "UPDATE TempSession SET Quantity = " & intQuantity.ToString & " WHERE SessionString LIKE '" & Me.Session.SessionID.ToStr ing & "' 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. DataGridCo mmandEvent Args) Handles dg.CancelCommand
dg.EditItemIndex = -1
LoadProductData()
CalculateTotal()
End Sub
Private Sub GetSelectedProductInfo()
Dim ProductID As String = Request.QueryString("Produ ctID")
Dim cnn As New OleDb.OleDbConnection(Conf igurationS ettings.Ap pSettings( "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(CommandB ehavior.Cl oseConnect ion)
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
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"))
Me.lblQuantity.Text = CInt(Session("Quantity")).
Me.lblSessionID.Text = CInt(Session("SessionID"))
Me.lblWeight.Text = CStr(Session("Weight"))
Session("SessionID") = Me.lblSessionID.Text.ToStr
GetSelectedProductInfo()
LoadProductData()
CalculateTotal()
End If
End Sub
Private Sub LoadProductData()
Dim cnn As New OleDb.OleDbConnection(Conf
Dim cmd As New OleDb.OleDbCommand
cmd.CommandType = CommandType.Text
cmd.CommandText = "SELECT TempSession.SessionID, TempSession.SessionString,
"WHERE SessionString = '" & Me.Session.SessionID & "'"
cmd.Connection = cnn
cnn.Open()
dg.DataSource = cmd.ExecuteReader
dg.DataBind()
Me.HyperLink1.NavigateUrl = "ProductDetails.aspx?pid="
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(Conf
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.ToStr
cmd.Connection = cnn
cnn.Open()
dr = cmd.ExecuteReader(CommandB
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.
Dim cnn As New OleDb.OleDbConnection(Conf
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.
dg.EditItemIndex = e.Item.ItemIndex
LoadProductData()
CalculateTotal()
End Sub
Private Sub dg_UpdateCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.
Dim cnn As New OleDb.OleDbConnection(Conf
Dim cmd As New OleDb.OleDbCommand
Dim intQuantity As String = CType(e.Item.Cells(3).Cont
cmd.CommandType = CommandType.Text
cmd.CommandText = "UPDATE TempSession SET Quantity = " & intQuantity.ToString & " WHERE SessionString LIKE '" & Me.Session.SessionID.ToStr
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.
dg.EditItemIndex = -1
LoadProductData()
CalculateTotal()
End Sub
Private Sub GetSelectedProductInfo()
Dim ProductID As String = Request.QueryString("Produ
Dim cnn As New OleDb.OleDbConnection(Conf
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(CommandB
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
ASKER
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.
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.
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.
Best, Nauman.
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