?
Solved

Viewstate problem when removing row

Posted on 2005-03-16
30
Medium Priority
?
395 Views
Last Modified: 2008-02-01
Hi,

The following code create dynamic controls with Button1_Click and removes checked rows with Button4_Click and Button5_Click is used to add control's values to the access databse.

Everything working fine but the problem is:

suppose I create two rows and fill data in it and before submitting the form I delete first row then only one row there with data in it. when I click button_5 to add data to the databse the controls lose viewstate and no data is added to the databse. Except this problem I can keep viewstat and add to the db.

Private Sub Button4_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button4.Click
        Dim i As Integer = tblSpareParts.Rows.Count - 1
        While i >= 0
            Dim tr As HtmlTableRow = tblSpareParts.Rows(i)
            Dim chk1 As CheckBox = CType(tr.Cells(4).Controls(1), CheckBox)
            If chk1.Checked Then
                tblSpareParts.Rows.RemoveAt(i)
                Dim cnt As Integer = 0
                cnt = CInt(Session("Count")) - 1
                Session.Item("Count") = cnt
            End If
            Math.Max(Threading.Interlocked.Decrement(i), i + 1)
        End While
    End Sub

Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
        Dim cnt As Integer = 0
        cnt = CInt(Session("Count")) + 1
        Session.Item("Count") = cnt
        AddARow(cnt)
    End Sub
could anyone hlep to find what's wrong?

ayha
0
Comment
Question by:ayha1999
[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
  • 14
  • 13
  • 2
  • +1
30 Comments
 
LVL 26

Expert Comment

by:Rejojohny
ID: 13554482
can u also post cod efor button5 ... am suprised how the code seems to be working as i have read that all dynamically created controls have to created everytime the page is submitted .. then how come ur controls are still present when button4 is clicked .. could u also post the code for AddARow ...
0
 
LVL 26

Expert Comment

by:Rejojohny
ID: 13554537
i just noticed ur questinon subject is "Viewstate problem when removing row" and u have mentioned above "Everything working fine but the problem is:" .. so do u mean to say the removing of row is working fine or not and u r facing problems with updating the data ...
0
 
LVL 23

Expert Comment

by:b1xml2
ID: 13554579
Based on what you have written I would suggest the following:

1.  Persist the actual data in ViewState. You could store say a DataTable in ViewState.
2.  Re-create the dynamic controls whenever a new row is added.
3.  You are better off using DataGrid or Repeater Control instead of the Table control.


0
Industry Leaders: 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!

 
LVL 26

Expert Comment

by:Rejojohny
ID: 13554625
0
 
LVL 7

Author Comment

by:ayha1999
ID: 13555568
pls. find the complete code :

    Private Sub CreateMyControls()
        Dim Counter As Integer = (CInt(Session("Count")))
        For I As Integer = 1 To Counter
            AddARow(I)
        Next
    End Sub

    Private Sub AddARow(ByVal rowNum As Integer)

        Dim sqlstr As String = "select * from SpareParts"

        Dim txtPartNo As DropDownList = New DropDownList
        Dim txtPartQty As TextBox = New TextBox
        Dim chkRowDel As CheckBox = New CheckBox
        Dim tblRow As HtmlTableRow = New HtmlTableRow

        Dim valPartNo As RequiredFieldValidator = New RequiredFieldValidator
        Dim valQty As RequiredFieldValidator = New RequiredFieldValidator

        tblSpareParts.Rows.Add(New HtmlTableRow)

        tblSpareParts.Rows(tblSpareParts.Rows.Count - 1).Cells.Add(New HtmlTableCell)
        tblSpareParts.Rows(tblSpareParts.Rows.Count - 1).Cells.Add(New HtmlTableCell)
        tblSpareParts.Rows(tblSpareParts.Rows.Count - 1).Cells.Add(New HtmlTableCell)
        tblSpareParts.Rows(tblSpareParts.Rows.Count - 1).Cells.Add(New HtmlTableCell)
        tblSpareParts.Rows(tblSpareParts.Rows.Count - 1).Cells.Add(New HtmlTableCell)

        txtPartQty.Width = Unit.Pixel(35)

        txtPartNo.ID = "txtPartNo_" & rowNum.ToString
        txtPartQty.ID = "txtPartQty_" & rowNum.ToString
        chkRowDel.ID = "chkRowDel_" & rowNum.ToString

        txtPartNo.DataSource = General.GetDr(sqlstr)
        txtPartNo.DataTextField = "PartNo"
        txtPartNo.DataValueField = "PartNo"
        txtPartNo.DataBind()
        txtPartNo.Items.Insert(0, New ListItem("-Not selected-", ""))

        valPartNo.ControlToValidate = txtPartNo.ID
        valPartNo.ErrorMessage = "Part No. required."
        valQty.ControlToValidate = txtPartQty.ID
        valQty.ErrorMessage = "Qty. required."

        tblSpareParts.Rows(tblSpareParts.Rows.Count - 1).Cells(0).Controls.Add(txtPartNo)
        tblSpareParts.Rows(tblSpareParts.Rows.Count - 1).Cells(1).Controls.Add(valPartNo)
        tblSpareParts.Rows(tblSpareParts.Rows.Count - 1).Cells(2).Controls.Add(txtPartQty)
        tblSpareParts.Rows(tblSpareParts.Rows.Count - 1).Cells(3).Controls.Add(valQty)
        tblSpareParts.Rows(tblSpareParts.Rows.Count - 1).Cells(4).Controls.Add(chkRowDel)
    End Sub

Private Sub Page_Init(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Init
        'CODEGEN: This method call is required by the Web Form Designer
        'Do not modify it using the code editor.
        InitializeComponent()

        If Not Page.IsPostBack Then
            Session("Count") = 0
        Else
            If Session("Count") > 0 Then
                CreateMyControls()
            End If
        End If
    End Sub

ayha
0
 
LVL 26

Expert Comment

by:Rejojohny
ID: 13555691
so u r creating the controls on each postback .. but then the viewstate for these controls will not be automatically maintained by ASP.net .. u will have to fill them manually .. using request.form("ControlName") ....
0
 
LVL 7

Author Comment

by:ayha1999
ID: 13556083
Hi Rejojohnuy,

asp.net keeps viewstate of the all the controls in the page after postback except the prblem I mentioned in my first post.

ayha
0
 
LVL 7

Author Comment

by:ayha1999
ID: 13557586
Hi,

I am just waiting for your reply.

ayha
0
 
LVL 26

Expert Comment

by:Rejojohny
ID: 13562461
i doubt whether it maintains the viewstate for dynamically created contrls .. did u try adding a new row .. adding some values and then submitting the page and see whether the values u entetred are there or not .. as u code in Addnewrow is seen, it seems u r binding some textbox to some values retreived from the database ..

have a look here on the order how a pge is loaded in asp.net .. the order of the events ..
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/aspnet-pageobjectmodel.asp
oder is ....
Page initialization
View state loading
Postback data processing
Page loading
Postback change notification
Postback event handling
....

u will notice that the viewstate of controls are loaded in the init and not after load .. so when u recreate all the controls in the load, the viewstate is already loaded and the controls will not have its old values .. that is the reason i was saying that dynamically created controls do not maintian the viewstate ...

have a look at these links for some ideas on how dynamic controls behave
http://www.experts-exchange.com/Programming/Programming_Languages/Dot_Net/Q_20765964.html
http://www.experts-exchange.com/Programming/Programming_Languages/Dot_Net/ASP_DOT_NET/Q_20992980.html
http://www.experts-exchange.com/Programming/Programming_Languages/Dot_Net/Q_20717399.html
http://www.experts-exchange.com/Programming/Programming_Languages/Dot_Net/Q_20711120.html
http://www.experts-exchange.com/Programming/Programming_Languages/Dot_Net/Q_20898174.html
0
 
LVL 7

Author Comment

by:ayha1999
ID: 13563883
Hi Rejojohny,

I as mentioned in my question, I can see dynamically created controls and its value after postback except the the prblem I mentieond there (pls. go through my question)

ayha
0
 
LVL 26

Expert Comment

by:Rejojohny
ID: 13564071
am really very sorry for not having noticed that u create the controls in the INIT event and not in the LOAD Event and the reason y the viewstate is maintained for the dynamic controls .. i think I got y u r facing the problem after deletetion .. say u load the page for the first time and add a row .. so ur session(cnt) now has value 1 .. u add one more and the session(cnt) has value 2 .. so ur controls created would be something like this

txtPartNo1          txtPartQty1          chkRowDel1
txtPartNo2          txtPartQty2          chkRowDel2

now lets say u click delete checkbox 4 the first row and click the delete button .. so ur controls would again get created as shown above and ur delete logic would remove off the 1st row .. and the page gets displayed with ur session(cnt) having value as 1 .. so the page would displayed would have the following controls

txtPartNo2          txtPartQty2          chkRowDel2

but now when u click the save button, the init function will create controls

txtPartNo1          txtPartQty1          chkRowDel1              (because ur logic to create controls just looks at the count)
AND NOT
txtPartNo2          txtPartQty2          chkRowDel2

and then try to restore values for these controls and they are not there .. as u have deleted them .. so these controls will have no value and then button5 (save) events logic tries to save empty values ... :-)))

try deleting the second row and then save .. am sure that will work :-)
0
 
LVL 7

Author Comment

by:ayha1999
ID: 13582200
What about if I want to delete the first row :-)?

ayha
0
 
LVL 8

Expert Comment

by:thrill_house
ID: 13592568
Asp.net does not persist state of dynamically created controls as you might think it does.  However, there is a work around to this.  You must create an id for each control, and have the id never change.  If the id doesn't change, asp.net will know where to restore the state of the dynamically created control.  Remember that everytime you recreate the control you need to make sure it has the same id.
0
 
LVL 8

Expert Comment

by:thrill_house
ID: 13592592
Try this:


 Private Sub AddARow(ByVal rowNum As Integer)

        Dim sqlstr As String = "select * from SpareParts"

        Dim txtPartNo As DropDownList = New DropDownList
        Dim txtPartQty As TextBox = New TextBox
        Dim chkRowDel As CheckBox = New CheckBox
        Dim tblRow As HtmlTableRow = New HtmlTableRow
        tblRow.id = "tblRow" & rowNum 'set the id


        Dim valPartNo As RequiredFieldValidator = New RequiredFieldValidator
        Dim valQty As RequiredFieldValidator = New RequiredFieldValidator

        tblSpareParts.Rows.Add(New HtmlTableRow)

        tblSpareParts.Rows(tblSpareParts.Rows.Count - 1).Cells.Add(New HtmlTableCell)
        tblSpareParts.Rows(tblSpareParts.Rows.Count - 1).Cells.Add(New HtmlTableCell)
        tblSpareParts.Rows(tblSpareParts.Rows.Count - 1).Cells.Add(New HtmlTableCell)
        tblSpareParts.Rows(tblSpareParts.Rows.Count - 1).Cells.Add(New HtmlTableCell)
        tblSpareParts.Rows(tblSpareParts.Rows.Count - 1).Cells.Add(New HtmlTableCell)

        txtPartQty.Width = Unit.Pixel(35)

        txtPartNo.ID = "txtPartNo_" & rowNum.ToString
        txtPartQty.ID = "txtPartQty_" & rowNum.ToString
        chkRowDel.ID = "chkRowDel_" & rowNum.ToString

        txtPartNo.DataSource = General.GetDr(sqlstr)
        txtPartNo.DataTextField = "PartNo"
        txtPartNo.DataValueField = "PartNo"
        txtPartNo.DataBind()
        txtPartNo.Items.Insert(0, New ListItem("-Not selected-", ""))

        valPartNo.ControlToValidate = txtPartNo.ID
        valPartNo.ErrorMessage = "Part No. required."
        valQty.ControlToValidate = txtPartQty.ID
        valQty.ErrorMessage = "Qty. required."

        tblSpareParts.Rows(tblSpareParts.Rows.Count - 1).Cells(0).Controls.Add(txtPartNo)
        tblSpareParts.Rows(tblSpareParts.Rows.Count - 1).Cells(1).Controls.Add(valPartNo)
        tblSpareParts.Rows(tblSpareParts.Rows.Count - 1).Cells(2).Controls.Add(txtPartQty)
        tblSpareParts.Rows(tblSpareParts.Rows.Count - 1).Cells(3).Controls.Add(valQty)
        tblSpareParts.Rows(tblSpareParts.Rows.Count - 1).Cells(4).Controls.Add(chkRowDel)
    End Sub
0
 
LVL 7

Author Comment

by:ayha1999
ID: 13593844
Hi thrill house,

first of all this is an HTML table to set an ID. I tried your modification but the result is same. what modification has to be made in delete row sub after setting the ID? If u read my question completely, the prblem happens only when deleting row. I can keep controls and view state except the the problem I mentioned.

ayha
0
 
LVL 26

Expert Comment

by:Rejojohny
ID: 13598375
thrill house,
All this has already been discussed with ayha1999 .. the problem is not about viewstate not been maintained but with the logic been used .. what has to be done is ayha1999 will have to keep a list of the ids(rows) which has been deleted .. the "cnt" session variable counter will never decrease when a row is deleted .. just another hidden textbox will be updated with the id that has been deleted .. so whenver the row is re-created in the init, it will be first checked in this hidden textbox (containing the deleted ids) to verify if the id is present .. if s, then just skip that cnt and move to the next id ..
0
 
LVL 7

Author Comment

by:ayha1999
ID: 13624915
Hi,

please if anyone has solution.

ayha
0
 
LVL 26

Expert Comment

by:Rejojohny
ID: 13630058
I have already shown what the problem is and also suggested a solution .. pls comment on what is the the problem still ??
0
 
LVL 7

Author Comment

by:ayha1999
ID: 13630127
Hi Rejojohny,

I have already commented that when I remove second row and try to save then no p\roblem and I get data in table. But when I remove the first row the problem happens. Here I need your help.

ayha
0
 
LVL 26

Expert Comment

by:Rejojohny
ID: 13638714
Pls read my comment "Date: 03/22/2005 08:44AM AST" .. i have advised you to manage the "cnt" variable a bit intellengently .. i have given u the reason y it is not working and also an idea how the logic should be changed to solve the problem .. what more do u need?
0
 
LVL 7

Author Comment

by:ayha1999
ID: 13644766
Hi Rejojohny,

Still I am not able fix the problem. Could u pls. help me in this regard?

thanks in advance.

ayha
0
 
LVL 26

Expert Comment

by:Rejojohny
ID: 13649831
what exactly is the problem now? r u getin an error .. r u not able to change the logic?
0
 
LVL 7

Author Comment

by:ayha1999
ID: 13652480
Hi Rejojohny,

I am not able to change the logic.

ayha
0
 
LVL 26

Accepted Solution

by:
Rejojohny earned 2000 total points
ID: 13653400
is this not ur code? y can't u change the logic? i have explained what has to be done ...
add a hidden text field
<input id=hidDeletedRows type = hidden runat = 0>

in the delete button's click event i.e. button4
Private Sub Button4_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button4.Click
        Dim i As Integer = tblSpareParts.Rows.Count - 1
        While i >= 0
            Dim tr As HtmlTableRow = tblSpareParts.Rows(i)
            Dim chk1 As CheckBox = CType(tr.Cells(4).Controls(1), CheckBox)
            If chk1.Checked Then
                tblSpareParts.Rows.RemoveAt(i)
                'Dim cnt As Integer = 0
                'cnt = CInt(Session("Count")) - 1 .. comment these line .. instead update the hidden field
                'Session.Item("Count") = cnt
                 hidDeletedRows.value = hidDeletedRows & ";" & i
            End If
            Math.Max(Threading.Interlocked.Decrement(i), i + 1)
        End While
    End Sub

ur CreateRow function will change to check if the row is in the deleted list .. if s, then that row will not be created
    Private Sub CreateMyControls()
        Dim Counter As Integer = (CInt(Session("Count")))
        Dim lstrDeletedRows as string = hidDeltedRows.value
        For I As Integer = 1 To Counter
           if instr(lstrDletedRows, i,CompareMethod.Binary) = 0 then
                 AddARow(I)
           end if
        Next
    End Sub
0
 
LVL 7

Author Comment

by:ayha1999
ID: 13654625
Hi Rejojonhy,,

I got the error;

error at   If InStr(lstrDeletedRows, I, CompareMethod.Binary) = 0 in the create controls.

Overload resolution failed because no accessible 'InStr' can be called without a narrowing conversion:
    'Public Function InStr(Start As Integer, String1 As String, String2 As String, [Compare As Microsoft.VisualBasic.CompareMethod = Microsoft.VisualBasic.CompareMethod.Binary]) As Integer': Argument matching parameter 'Start' narrows from 'String' to 'Integer'.
    'Public Function InStr(Start As Integer, String1 As String, String2 As String, [Compare As Microsoft.VisualBasic.CompareMethod = Microsoft.VisualBasic.CompareMethod.Binary]) As Integer': Argument matching parameter 'String1' narrows from 'Integer' to 'String'.
    'Public Function InStr(Start As Integer, String1 As String, String2 As String, [Compare As Microsoft.VisualBasic.CompareMethod = Microsoft.VisualBasic.CompareMethod.Binary]) As Integer': Argument matching parameter 'String2' narrows from 'Microsoft.VisualBasic.CompareMethod' to 'String'.
    'Public Function InStr(String1 As String, String2 As String, [Compare As Microsoft.VisualBasic.CompareMethod = Microsoft.VisualBasic.CompareMethod.Binary]) As Integer': Argument matching parameter 'String2' narrows from 'Integer' to 'String'.

error at hidDeletedRows & ";" & i in button4_click

Operator '&' is not defined for types 'System.Web.UI.HtmlControls.HtmlInputHidden' and 'String'.

ayha
0
 
LVL 26

Expert Comment

by:Rejojohny
ID: 13659182
it whould be hidDeletedRows.value = hidDeletedRows.value & ";" & i
and
if instr(lstrDeletedRows, cstr(I),CompareMethod.Binary) = 0 then
or
if instr(lstrDeletedRows, cstr(I)) = 0 then or


mind u i have not tested all this .. i just assume u have enough experience to correct syntax errors
0
 
LVL 7

Author Comment

by:ayha1999
ID: 13717797
Hi Rejojohny,

I have tested your code the result is as follows;

Suppose I create two rows and fill then I delete first row and when I click on save then an empty row is created in the first row and the original row move to second and but data is saved in the db.

suppose I create five rows and delete first four and click on add row again then instead of creating one row it creates 5 rows (four deleted rows + a new row).

Is there any workaround for the above problems?

ayha
0
 
LVL 26

Expert Comment

by:Rejojohny
ID: 13717855
>>suppose I create five rows and delete first four and click on add row again then instead of creating one row it creates 5 rows
debug and check what is happening as this is not what is supposed to happen .. the deletedids should have the list of all the 4 ids and so should not be created .. just whther the deleted ids hidden field has the ids present
0
 
LVL 7

Author Comment

by:ayha1999
ID: 13748041
Hi Rejojohny,

I think it is better to use insertable datagrid instead of dynamic controls.

anyway thanks for your help.

ayha
0
 
LVL 26

Expert Comment

by:Rejojohny
ID: 13751727
true and that is what i was trying to exaplin in my comments dated 03/16/2005 03:46PM AST :-) .. thx for the pnts !! all the best
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

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…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
Monitoring a network: how to monitor network services and why? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the philosophy behind service monitoring and why a handshake validation is critical in network monitoring. Software utilized …
In this video, Percona Director of Solution Engineering Jon Tobin discusses the function and features of Percona Server for MongoDB. How Percona can help Percona can help you determine if Percona Server for MongoDB is the right solution for …
Suggested Courses

770 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