C
Chad
I have a problem that I am desperate to understand.
It involves dynamically adding controls to a Table control that is built as a result of performing a database query.
I am not looking to avoid the problem by avoiding the table control or resorting to databound controls that better manage state for me. I hope to understand how to solve the problem by using the Table web control and sticking to the approach of building the table at run time rather than using databound controls.
I tried to create the shortest code example that, when run, illustrates the problem.
This is basically what I want to do:
1) I want to query a table, Table1, which has two columns, "KeyCol" (PK int) and "Hide" (bit).
2) I want to return all the rows where the Hide flag is not set to 1.
3) For each returned row, I want to use the Table control to dynamically add a row to the Table for each record returned by the above query.
4) For each TableRow created, I will add 2 TableCells (columns). The first column wil be display the KeyCol value returned.
5) In the 2nd column, I will display a blank text box.
6) If the user type ANY text in the text box and pushes the BUTTON at the bottom of the page, this will update the HIDE flag for the selected record in Table1.
7) The display will then be refreshed. Since the query excludes recs where the Hide flag is set, this record will be removed from the table after the refresh,
Now the problem....
Everything works fine up to this point. But the next time that the user enters text in one of the remaining textboxes and pushes the BUTTON, the logic does not detect that there is any text in the text box! Howver, on the NEXT submit, the value will be detected!
This is my understanding:
In order to determine if a value was typed in the text box since the last submit, the table must be REBUILT each time. However, if the TABLE is redrawn (all rows removed and rebuilt), I think the view state is getting out of sync somehow (not sure!).
I assume that the answer to this problem is just a tweek somewhere. Can someone help. I've spend too many hours on what should be a basic problem.
Below is everything you should need to have a running example of what I am doing.
I would be greatly appreciative to any help. Thanks
------------------------------------------------------------------------------------------------------------------
CREATE TABLE [dbo].[Table1]
(
[KeyCol] [int] NOT NULL IDENTITY(1, 1),
[Hide] [bit] NOT NULL
)
GO
-- Constraints and indexes
ALTER TABLE [dbo].[Table1] ADD CONSTRAINT [PK_Table1] PRIMARY KEY CLUSTERED ([KeyCol])
GO
BEGIN TRANSACTION
SET IDENTITY_INSERT [dbo].[Table1] ON
INSERT INTO [dbo].[Table1] ([KeyCol], [Hide]) VALUES (1, 0)
INSERT INTO [dbo].[Table1] ([KeyCol], [Hide]) VALUES (2, 0)
INSERT INTO [dbo].[Table1] ([KeyCol], [Hide]) VALUES (3, 0)
INSERT INTO [dbo].[Table1] ([KeyCol], [Hide]) VALUES (4, 0)
INSERT INTO [dbo].[Table1] ([KeyCol], [Hide]) VALUES (5, 0)
INSERT INTO [dbo].[Table1] ([KeyCol], [Hide]) VALUES (6, 0)
INSERT INTO [dbo].[Table1] ([KeyCol], [Hide]) VALUES (7, 0)
SET IDENTITY_INSERT [dbo].[Table1] OFF
COMMIT TRANSACTION
-----------------------------------------------------------------------------
Imports System.Web.UI.WebControls
Imports System.Data.SqlClient
Public Class WebForm1
Inherits System.Web.UI.Page
#Region " Web Form Designer Generated Code "
'This call is required by the Web Form Designer.
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
End Sub
Protected WithEvents Button1 As System.Web.UI.WebControls.Button
Protected WithEvents Table1 As System.Web.UI.WebControls.Table
'NOTE: The following placeholder declaration is required by the Web Form Designer.
'Do not delete or move it.
Private designerPlaceholderDeclaration As System.Object
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub
#End Region
Dim SqlConnection As SqlConnection
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
SqlConnection = New SqlConnection("server=(local);database=skpirepository;uid=skpiuser;pwd=skpiuser")
SqlConnection.Open()
BuildTable()
End Sub
Private Sub BuildTable()
Dim TableRow As TableRow
Dim TableCell As TableCell
Dim TextBox As TextBox
Dim ds As New DataSet
Dim DataRow As DataRow
Dim SqlDataAdapter As New SqlDataAdapter("Select * from table1 where Hide <> 1", SqlConnection)
SqlDataAdapter.Fill(ds, "table1")
For Each DataRow In ds.Tables(0).Rows
'Add Row
TableRow = New TableRow
Table1.Rows.Add(TableRow)
'Add 1st Col Cell
TableCell = New TableCell
TableCell.Text = DataRow.Item("KeyCol").ToString
TableRow.Cells.Add(TableCell)
'Add 2nd Col TextBox
TableCell = New TableCell
TableRow.Cells.Add(TableCell)
TextBox = New TextBox
TableCell.Controls.Add(TextBox)
Table1.Rows.Add(TableRow)
Next
End Sub
Private Sub ClearRows()
Dim r As Integer
For r = Table1.Rows.Count - 1 To 0 Step -1
Table1.Rows.Remove(Table1.Rows.Item(r))
Next
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim TableRow As TableRow
Dim TextBox As TextBox
Dim KeyCol As Integer
Dim RefreshTable As Boolean = False
For Each TableRow In Table1.Rows
KeyCol = CType(TableRow.Cells(0).Text, Integer)
TextBox = CType(TableRow.Cells(1).Controls(0), TextBox)
If Trim(TextBox.Text) <> "" Then
Dim SqlCommand As New SqlCommand("UPDATE Table1 SET Hide = 1 WHERE KeyCol = " & KeyCol.ToString, SqlConnection)
SqlCommand.ExecuteNonQuery()
RefreshTable = True
End If
Next
If RefreshTable Then
ClearRows()
BuildTable()
End If
End Sub
End Class
----------------------------------------------------------------------------------------------------------
<%@ Page Language="vb" AutoEventWireup="false" Codebehind="WebForm1.aspx.vb" Inherits="WebApplication2.WebForm1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<title>WebForm1</title>
<meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR">
<meta content="Visual Basic .NET 7.1" name="CODE_LANGUAGE">
<meta content="JavaScript" name="vs_defaultClientScript">
<meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
</HEAD>
<body>
<form id="Form1" method="post" runat="server">
<asp:table id="Table1" runat="server"></asp:table>
<asp:button id="Button1" runat="server" Text="Type anything in the text box to remove that row"></asp:button></form>
</body>
</HTML>
It involves dynamically adding controls to a Table control that is built as a result of performing a database query.
I am not looking to avoid the problem by avoiding the table control or resorting to databound controls that better manage state for me. I hope to understand how to solve the problem by using the Table web control and sticking to the approach of building the table at run time rather than using databound controls.
I tried to create the shortest code example that, when run, illustrates the problem.
This is basically what I want to do:
1) I want to query a table, Table1, which has two columns, "KeyCol" (PK int) and "Hide" (bit).
2) I want to return all the rows where the Hide flag is not set to 1.
3) For each returned row, I want to use the Table control to dynamically add a row to the Table for each record returned by the above query.
4) For each TableRow created, I will add 2 TableCells (columns). The first column wil be display the KeyCol value returned.
5) In the 2nd column, I will display a blank text box.
6) If the user type ANY text in the text box and pushes the BUTTON at the bottom of the page, this will update the HIDE flag for the selected record in Table1.
7) The display will then be refreshed. Since the query excludes recs where the Hide flag is set, this record will be removed from the table after the refresh,
Now the problem....
Everything works fine up to this point. But the next time that the user enters text in one of the remaining textboxes and pushes the BUTTON, the logic does not detect that there is any text in the text box! Howver, on the NEXT submit, the value will be detected!
This is my understanding:
In order to determine if a value was typed in the text box since the last submit, the table must be REBUILT each time. However, if the TABLE is redrawn (all rows removed and rebuilt), I think the view state is getting out of sync somehow (not sure!).
I assume that the answer to this problem is just a tweek somewhere. Can someone help. I've spend too many hours on what should be a basic problem.
Below is everything you should need to have a running example of what I am doing.
I would be greatly appreciative to any help. Thanks
------------------------------------------------------------------------------------------------------------------
CREATE TABLE [dbo].[Table1]
(
[KeyCol] [int] NOT NULL IDENTITY(1, 1),
[Hide] [bit] NOT NULL
)
GO
-- Constraints and indexes
ALTER TABLE [dbo].[Table1] ADD CONSTRAINT [PK_Table1] PRIMARY KEY CLUSTERED ([KeyCol])
GO
BEGIN TRANSACTION
SET IDENTITY_INSERT [dbo].[Table1] ON
INSERT INTO [dbo].[Table1] ([KeyCol], [Hide]) VALUES (1, 0)
INSERT INTO [dbo].[Table1] ([KeyCol], [Hide]) VALUES (2, 0)
INSERT INTO [dbo].[Table1] ([KeyCol], [Hide]) VALUES (3, 0)
INSERT INTO [dbo].[Table1] ([KeyCol], [Hide]) VALUES (4, 0)
INSERT INTO [dbo].[Table1] ([KeyCol], [Hide]) VALUES (5, 0)
INSERT INTO [dbo].[Table1] ([KeyCol], [Hide]) VALUES (6, 0)
INSERT INTO [dbo].[Table1] ([KeyCol], [Hide]) VALUES (7, 0)
SET IDENTITY_INSERT [dbo].[Table1] OFF
COMMIT TRANSACTION
-----------------------------------------------------------------------------
Imports System.Web.UI.WebControls
Imports System.Data.SqlClient
Public Class WebForm1
Inherits System.Web.UI.Page
#Region " Web Form Designer Generated Code "
'This call is required by the Web Form Designer.
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
End Sub
Protected WithEvents Button1 As System.Web.UI.WebControls.Button
Protected WithEvents Table1 As System.Web.UI.WebControls.Table
'NOTE: The following placeholder declaration is required by the Web Form Designer.
'Do not delete or move it.
Private designerPlaceholderDeclaration As System.Object
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub
#End Region
Dim SqlConnection As SqlConnection
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
SqlConnection = New SqlConnection("server=(local);database=skpirepository;uid=skpiuser;pwd=skpiuser")
SqlConnection.Open()
BuildTable()
End Sub
Private Sub BuildTable()
Dim TableRow As TableRow
Dim TableCell As TableCell
Dim TextBox As TextBox
Dim ds As New DataSet
Dim DataRow As DataRow
Dim SqlDataAdapter As New SqlDataAdapter("Select * from table1 where Hide <> 1", SqlConnection)
SqlDataAdapter.Fill(ds, "table1")
For Each DataRow In ds.Tables(0).Rows
'Add Row
TableRow = New TableRow
Table1.Rows.Add(TableRow)
'Add 1st Col Cell
TableCell = New TableCell
TableCell.Text = DataRow.Item("KeyCol").ToString
TableRow.Cells.Add(TableCell)
'Add 2nd Col TextBox
TableCell = New TableCell
TableRow.Cells.Add(TableCell)
TextBox = New TextBox
TableCell.Controls.Add(TextBox)
Table1.Rows.Add(TableRow)
Next
End Sub
Private Sub ClearRows()
Dim r As Integer
For r = Table1.Rows.Count - 1 To 0 Step -1
Table1.Rows.Remove(Table1.Rows.Item(r))
Next
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim TableRow As TableRow
Dim TextBox As TextBox
Dim KeyCol As Integer
Dim RefreshTable As Boolean = False
For Each TableRow In Table1.Rows
KeyCol = CType(TableRow.Cells(0).Text, Integer)
TextBox = CType(TableRow.Cells(1).Controls(0), TextBox)
If Trim(TextBox.Text) <> "" Then
Dim SqlCommand As New SqlCommand("UPDATE Table1 SET Hide = 1 WHERE KeyCol = " & KeyCol.ToString, SqlConnection)
SqlCommand.ExecuteNonQuery()
RefreshTable = True
End If
Next
If RefreshTable Then
ClearRows()
BuildTable()
End If
End Sub
End Class
----------------------------------------------------------------------------------------------------------
<%@ Page Language="vb" AutoEventWireup="false" Codebehind="WebForm1.aspx.vb" Inherits="WebApplication2.WebForm1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<title>WebForm1</title>
<meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR">
<meta content="Visual Basic .NET 7.1" name="CODE_LANGUAGE">
<meta content="JavaScript" name="vs_defaultClientScript">
<meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
</HEAD>
<body>
<form id="Form1" method="post" runat="server">
<asp:table id="Table1" runat="server"></asp:table>
<asp:button id="Button1" runat="server" Text="Type anything in the text box to remove that row"></asp:button></form>
</body>
</HTML>