Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 399
  • Last Modified:

Viewstate problem when removing row

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
ayha1999
Asked:
ayha1999
  • 14
  • 13
  • 2
  • +1
1 Solution
 
RejojohnyCommented:
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
 
RejojohnyCommented:
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
 
b1xml2Commented:
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
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!

 
RejojohnyCommented:
0
 
ayha1999Author Commented:
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
 
RejojohnyCommented:
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
 
ayha1999Author Commented:
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
 
ayha1999Author Commented:
Hi,

I am just waiting for your reply.

ayha
0
 
RejojohnyCommented:
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
 
ayha1999Author Commented:
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
 
RejojohnyCommented:
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
 
ayha1999Author Commented:
What about if I want to delete the first row :-)?

ayha
0
 
thrill_houseCommented:
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
 
thrill_houseCommented:
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
 
ayha1999Author Commented:
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
 
RejojohnyCommented:
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
 
ayha1999Author Commented:
Hi,

please if anyone has solution.

ayha
0
 
RejojohnyCommented:
I have already shown what the problem is and also suggested a solution .. pls comment on what is the the problem still ??
0
 
ayha1999Author Commented:
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
 
RejojohnyCommented:
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
 
ayha1999Author Commented:
Hi Rejojohny,

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

thanks in advance.

ayha
0
 
RejojohnyCommented:
what exactly is the problem now? r u getin an error .. r u not able to change the logic?
0
 
ayha1999Author Commented:
Hi Rejojohny,

I am not able to change the logic.

ayha
0
 
RejojohnyCommented:
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
 
ayha1999Author Commented:
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
 
RejojohnyCommented:
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
 
ayha1999Author Commented:
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
 
RejojohnyCommented:
>>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
 
ayha1999Author Commented:
Hi Rejojohny,

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

anyway thanks for your help.

ayha
0
 
RejojohnyCommented:
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

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!

  • 14
  • 13
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now