Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Shaun E on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

VB: Datatable either not saving data or data is being reset

Status
Not open for further replies.

Soteriologist

Programmer
May 26, 2006
9
US
I have a datatable that I'm trying to use for storing a matchup between two columns of dynamic controls (a span holding data on the left is matched up to choices from dropdownlists on the right).

I want the datable to save and store the data between postbacks but it seems to be resetting/not-saving.

The code I'm providing is a full working example (aspx and vb). On the page try picking something from one dropdownlist and see that it saves; then choose something from another dropdownlist and see that your new choice saves BUT your old choice for the other dropdownlist does not stay saved. Also try picking something in a dropdownlist (notice that it saves to the datable), then click the "div 2" button and notice that the data resets. (I'm talking about what data that is shown in the gridview and not by the controls themselves... actually this bring up another problem: I'm trying to have the dynamic controls display what is saved in datatable, but they don't seem to be.)

Essentially what I'm trying to accomplish is the following:

If the datatable is empty (a.k.a. the page is loading for the first time) build the dynamic controls and try to automatch values.
If the datatable is filled with data, then build the dynamic controls and select values for the dropdownlist based off of what is saved in the datatable.
When a user chooses something in one of the dropdownlists AND that value hasn't already been picked in another dropdownlist save that value to the datatable
If the user chooses something that already has been picked, then display an error message and don't save the value to the datatable.

Here's the ASPX:

Code:
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="Testing_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "[URL unfurl="true"]http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">[/URL]
<html xmlns="[URL unfurl="true"]http://www.w3.org/1999/xhtml">[/URL]
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <div id="Div1_div" runat="server" visible="false">
            <asp:Button ID="Div1_btn" runat="server" Text="Div 2" /><br />
            <asp:GridView ID="Page1_gv" runat="server">
                <AlternatingRowStyle BackColor="#F5F5F5" />
                <SelectedRowStyle BackColor="#FFFF00" />
            </asp:GridView>
            Left Index:<asp:TextBox ID="LeftIndex_txtbx" runat="server"></asp:TextBox>
            Right DDL Index:<asp:TextBox ID="RightIndex_txtbx" runat="server"></asp:TextBox>
            Right Number:<asp:TextBox ID="RightNumber_txtbx" runat="server"></asp:TextBox><br />
            <p id="DuplicateNumberWarning_p" runat="server" style="color:#ff0000; display:none;">&nbsp&nbsp&nbsp&nbsp&nbsp
                The column that you chose is already in use.
            </p>
            <asp:PlaceHolder ID="Numbers_ph" runat="server" />
        </div>
        <div id="Div2_div" runat="server" visible="false">
            <asp:Button ID="Div2_btn" runat="server" Text="Div 1" /><br />
            <asp:GridView ID="Div2_gv" runat="server">
                <AlternatingRowStyle BackColor="#F5F5F5" />
                <SelectedRowStyle BackColor="#FFFF00" />
            </asp:GridView>
        </div>
    </div>
    </form>
</body>
</html>

Here's the VB.NET:

Code:
Imports System.Data
Imports System.Data.SqlClient
Partial Class Testing_Default
    Inherits System.Web.UI.Page
    Protected Numbers_dt As DataTable = New DataTable("Numbers")
    Protected Number_nr As DataRow
    Protected Sub Page_Init(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Init
        With Numbers_dt
            .Columns.Add("u_LeftNumber", System.Type.GetType("System.String"))
            .Columns.Add("i_RightIndex", System.Type.GetType("System.Int32"))
            .Columns.Add("u_RightNumber", System.Type.GetType("System.String"))
        End With
    End Sub
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
        If Not (Page.IsPostBack) Then
            Div1_div.Visible = True
        End If
    End Sub
#Region " Div 1 "
    Protected Sub Div1_div_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Div1_div.Load
        GenerateNumbersList()
        Page1_gv.DataSource = Numbers_dt
        Page1_gv.DataBind()
    End Sub
    Protected Sub GenerateNumbersList()
        Dim Counter As Integer
        Dim Number As String
        Dim LeftNumber_sp As New HtmlGenericControl
        Dim RightNumbers_ddl As New DropDownList
        Dim Numbers_dtEmpty As Boolean
        If (Numbers_dt.Rows.Count > 0) Then
            Numbers_dtEmpty = False
        Else
            Numbers_dtEmpty = True
        End If
        While (Counter < 5)
            Number = (Counter + 1).ToString()
            LeftNumber_sp = New HtmlGenericControl
            With LeftNumber_sp
                .ID = "LeftNumber" & Number & "_sp"
                .InnerText = Number
            End With
            RightNumbers_ddl = GenerateNumbers_ddl(Counter, Number, Numbers_dtEmpty)
            Numbers_ph.Controls.Add(LeftNumber_sp)
            Numbers_ph.Controls.Add(RightNumbers_ddl)
            Numbers_ph.Controls.Add(New LiteralControl("<br /><br />"))
            Counter += 1
        End While
    End Sub
    Protected Function GenerateNumbers_ddl(ByVal IDCounter As Integer, ByVal LeftNumber As String, ByVal Numbers_dtEmpty As Boolean) As DropDownList
        Dim Blank_li As ListItem = New ListItem("", "")
        Dim One_li As ListItem = New ListItem("One", "One")
        Dim Two_li As ListItem = New ListItem("2", "2")
        Dim Three_li As ListItem = New ListItem("Three", "Three")
        Dim Four_li As ListItem = New ListItem("4", "4")
        Dim Five_li As ListItem = New ListItem("Five", "Five")
        Dim ddl As New DropDownList
        With ddl
            .ID = "RightNumbers" & IDCounter.ToString() & "_ddl"
            .CssClass = "float_l"
            .Style.Item("width") = "50px"
            .AutoPostBack = True
            .Items.Add(Blank_li)
            .Items.Add(One_li)
            .Items.Add(Two_li)
            .Items.Add(Three_li)
            .Items.Add(Four_li)
            .Items.Add(Five_li)
        End With
        If (Numbers_dtEmpty = True) Then
            Number_nr = Numbers_dt.NewRow()
            Number_nr("u_LeftNumber") = IDCounter.ToString()
            For Each ListItem In ddl.Items
                If (ListItem.Text.Length > 0) And (LeftNumber.Length > 0) Then
                    If (ListItem.Text.Substring(0, 1).ToLower = LeftNumber.Substring(0, 1).ToLower) Then
                        ListItem.Selected = True
                        Exit For
                    End If
                End If
            Next
            If (ddl.SelectedIndex <> 0) Then
                Number_nr("i_RightIndex") = ddl.SelectedIndex
            Else
                Number_nr("i_RightIndex") = 0
            End If
            Number_nr("u_RightNumber") = ddl.SelectedValue
            Numbers_dt.Rows.Add(Number_nr)
        Else
            ddl.SelectedIndex = Numbers_dt.Rows(IDCounter).Item("i_RightIndex")
        End If
        AddHandler ddl.SelectedIndexChanged, AddressOf DBHeader_ddl_SelectedIndexChanged
        Return ddl
    End Function
    Protected Sub DBHeader_ddl_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim ddl As DropDownList = DirectCast(sender, DropDownList)
        Dim selectedIndex, rowNumber As Integer
        Dim selectedValue, selectedText As String
        With ddl
            selectedIndex = .SelectedIndex
            selectedValue = .SelectedValue
            selectedText = .SelectedItem.Text
            rowNumber = CInt(.ClientID.ToString().Replace("RightNumbers", "").Replace("_ddl", ""))
        End With
        Dim rowCounter As Integer
        Dim foundMatch As Boolean
        If (selectedIndex <> 0) Then
            While (rowCounter < Numbers_dt.Rows.Count())
                If (Numbers_dt.Rows(rowCounter).Item("i_RightIndex") = selectedIndex) And (Numbers_dt.Rows(rowCounter).Item("u_LeftNumber") <> (rowNumber.ToString())) Then
                    foundMatch = True
                    Exit While
                Else
                    foundMatch = False
                End If
                rowCounter += 1
            End While
        Else
            foundMatch = False
        End If
        If (foundMatch = True) Then
            DuplicateNumberWarning_p.Style("display") = "block"
            DuplicateNumberWarning_p.InnerText = "Your selection was found to exist already in the datatable."
            Numbers_dt.Rows(rowNumber).BeginEdit()
            Numbers_dt.Rows(rowNumber).Item("i_RightIndex") = 0
            Numbers_dt.Rows(rowNumber).Item("u_RightNumber") = ""
            Numbers_dt.Rows(rowNumber).EndEdit()
            Numbers_dt.Rows(rowNumber).AcceptChanges()
        Else
            DuplicateNumberWarning_p.Style("display") = "none"
            Numbers_dt.Rows(rowNumber).BeginEdit()
            Numbers_dt.Rows(rowNumber).Item("i_RightIndex") = selectedIndex
            Numbers_dt.Rows(rowNumber).Item("u_RightNumber") = selectedValue
            Numbers_dt.Rows(rowNumber).EndEdit()
            Numbers_dt.Rows(rowNumber).AcceptChanges()
        End If
        LeftIndex_txtbx.Text = Numbers_dt.Rows(rowNumber).Item("u_LeftNumber")
        RightIndex_txtbx.Text = Numbers_dt.Rows(rowNumber).Item("i_RightIndex")
        RightNumber_txtbx.Text = Numbers_dt.Rows(rowNumber).Item("u_RightNumber")
        Page1_gv.DataBind()
    End Sub
    Protected Sub Page1_btn_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Div1_btn.Click
        Div1_div.Visible = False
        Div2_div.Visible = True
    End Sub
#End Region
#Region " Div 2 "
    Protected Sub Page2_div_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Div2_div.Load
        Div2_gv.DataSource = Numbers_dt
        Div2_gv.DataBind()
    End Sub
    Protected Sub Div2_btn_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Div2_btn.Click
        Div1_div.Visible = True
        Div2_div.Visible = False
    End Sub
#End Region
End Class
 
Someone from another forum was suspicious that it was the dynamic controls causing the problem.

But I've worked a lot with dynamic controls and everything with how I built them seemed to be working fine.

He gave a good suggestion though and so I've rebuilt the page with static controls to do some testing. Sure enough, even with static controls I'm still experiencing a problem with the datatable not saving.

Anyone think it might be that it's because my datatable is not attached to a datasource, like xml, access, sql server?

I think I'm going to try doing a write to xml and then bind to that xml file temporarily. I really didn't want to waste disk space and hdd read/write time for such a small transaction though. I would really prefer for it to stay in memory for the small time that it's needed.

Here's the aspx:

Code:
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default2.aspx.vb" Inherits="Testing_Default2" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "[URL unfurl="true"]http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">[/URL]
<html xmlns="[URL unfurl="true"]http://www.w3.org/1999/xhtml">[/URL]
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <div id="Div1_div" runat="server" visible="false">
            <asp:Button ID="Div1_btn" runat="server" Text="Div 2" /><br />
            <asp:GridView ID="Page1_gv" runat="server">
                <AlternatingRowStyle BackColor="#F5F5F5" />
                <SelectedRowStyle BackColor="#FFFF00" />
            </asp:GridView>
            DDL Control Index:<asp:TextBox ID="DDLControlIndex_txtbx" runat="server"></asp:TextBox>
            DDL Item Index:<asp:TextBox ID="DDLItemIndex_txtbx" runat="server"></asp:TextBox>
            DDL Item Value:<asp:TextBox ID="DDLItemValue_txtbx" runat="server"></asp:TextBox><br />
            <asp:DropDownList ID="DDL0_ddl" runat="server" AutoPostBack="true" OnSelectedIndexChanged="DBHeader_ddl_SelectedIndexChanged">
                <asp:ListItem Text="" Value=""></asp:ListItem>
                <asp:ListItem Text="One" Value="One"></asp:ListItem>
                <asp:ListItem Text="2" Value="2"></asp:ListItem>
                <asp:ListItem Text="Three" Value="Three"></asp:ListItem>
                <asp:ListItem Text="4" Value="4"></asp:ListItem>
                <asp:ListItem Text="Five" Value="Five"></asp:ListItem>
            </asp:DropDownList>
            <asp:DropDownList ID="DDL1_ddl" runat="server" AutoPostBack="true" OnSelectedIndexChanged="DBHeader_ddl_SelectedIndexChanged">
                <asp:ListItem Text="" Value=""></asp:ListItem>
                <asp:ListItem Text="One" Value="One"></asp:ListItem>
                <asp:ListItem Text="2" Value="2"></asp:ListItem>
                <asp:ListItem Text="Three" Value="Three"></asp:ListItem>
                <asp:ListItem Text="4" Value="4"></asp:ListItem>
                <asp:ListItem Text="Five" Value="Five"></asp:ListItem>
            </asp:DropDownList>
        </div>
        <div id="Div2_div" runat="server" visible="false">
            <asp:Button ID="Div2_btn" runat="server" Text="Div 1" /><br />
            <asp:GridView ID="Div2_gv" runat="server">
                <AlternatingRowStyle BackColor="#F5F5F5" />
                <SelectedRowStyle BackColor="#FFFF00" />
            </asp:GridView>
        </div>
    </div>
    </form>
</body>
</html>

And here's the VB.Net:

Code:
Imports System.Data
Imports System.Data.SqlClient
Partial Class Testing_Default2
    Inherits System.Web.UI.Page
    Protected Numbers_dt As DataTable = New DataTable("Numbers")
    Protected Number_nr As DataRow
    Protected Sub Page_Init(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.PreInit
        With Numbers_dt
            .Columns.Add("i_DDLItemIndex", System.Type.GetType("System.Int32"))
            .Columns.Add("u_DDLItemValue", System.Type.GetType("System.String"))
            Number_nr = .NewRow()
            Number_nr("i_DDLItemIndex") = 0
            Number_nr("u_DDLItemValue") = ""
            .Rows.Add(Number_nr)
            Number_nr = .NewRow()
            Number_nr("i_DDLItemIndex") = 0
            Number_nr("u_DDLItemValue") = ""
            .Rows.Add(Number_nr)
        End With
    End Sub
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
        If Not (Page.IsPostBack) Then
            Div1_div.Visible = True
        End If
    End Sub
#Region " Div 1 "
    Protected Sub Div1_div_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Div1_div.Init
        Page1_gv.DataSource = Numbers_dt
        Page1_gv.DataBind()
    End Sub
    Protected Sub DBHeader_ddl_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim ddl As DropDownList = DirectCast(sender, DropDownList)
        Dim selectedIndex, rowNumber As Integer
        Dim selectedValue, selectedText As String
        With ddl
            selectedIndex = .SelectedIndex
            selectedValue = .SelectedValue
            selectedText = .SelectedItem.Text
            rowNumber = CInt(.ClientID.ToString().Replace("DDL", "").Replace("_ddl", ""))
        End With
        DuplicateNumberWarning_p.Style("display") = "none"
        Numbers_dt.Rows(rowNumber).BeginEdit()
        Numbers_dt.Rows(rowNumber).Item("i_DDLItemIndex") = selectedIndex
        Numbers_dt.Rows(rowNumber).Item("u_DDLItemValue") = selectedValue
        Numbers_dt.Rows(rowNumber).EndEdit()
        Numbers_dt.Rows(rowNumber).AcceptChanges()
        DDLControlIndex_txtbx.Text = rowNumber.ToString()
        DDLItemIndex_txtbx.Text = Numbers_dt.Rows(rowNumber).Item("i_DDLItemIndex")
        DDLItemValue_txtbx.Text = Numbers_dt.Rows(rowNumber).Item("u_DDLItemValue")
        Page1_gv.DataBind()
    End Sub
    Protected Sub Page1_btn_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Div1_btn.Click
        Div1_div.Visible = False
        Div2_div.Visible = True
    End Sub
#End Region
#Region " Div 2 "
    Protected Sub Page2_div_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Div2_div.Load
        Div2_gv.DataSource = Numbers_dt
        Div2_gv.DataBind()
    End Sub
    Protected Sub Div2_btn_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Div2_btn.Click
        Div1_div.Visible = True
        Div2_div.Visible = False
    End Sub
#End Region
End Class
 
Well... Since I can't edit previous posts. There's a correction that needs to be made to my previous reply (NOT MY ORIGINAL POST... but my reply).

The codebehind had a bad line in it. Everthing else still applies.

Here's the proper VB.NET code:

Code:
Imports System.Data
Imports System.Data.SqlClient
Partial Class Testing_Default2
    Inherits System.Web.UI.Page
    Protected Numbers_dt As DataTable = New DataTable("Numbers")
    Protected Number_nr As DataRow
    Protected Sub Page_Init(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.PreInit
        With Numbers_dt
            .Columns.Add("i_DDLItemIndex", System.Type.GetType("System.Int32"))
            .Columns.Add("u_DDLItemValue", System.Type.GetType("System.String"))
            Number_nr = .NewRow()
            Number_nr("i_DDLItemIndex") = 0
            Number_nr("u_DDLItemValue") = ""
            .Rows.Add(Number_nr)
            Number_nr = .NewRow()
            Number_nr("i_DDLItemIndex") = 0
            Number_nr("u_DDLItemValue") = ""
            .Rows.Add(Number_nr)
        End With
    End Sub
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
        If Not (Page.IsPostBack) Then
            Div1_div.Visible = True
        End If
    End Sub
#Region " Div 1 "
    Protected Sub Div1_div_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Div1_div.Init
        Page1_gv.DataSource = Numbers_dt
        Page1_gv.DataBind()
    End Sub
    Protected Sub DBHeader_ddl_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim ddl As DropDownList = DirectCast(sender, DropDownList)
        Dim selectedIndex, rowNumber As Integer
        Dim selectedValue, selectedText As String
        With ddl
            selectedIndex = .SelectedIndex
            selectedValue = .SelectedValue
            selectedText = .SelectedItem.Text
            rowNumber = CInt(.ClientID.ToString().Replace("DDL", "").Replace("_ddl", ""))
        End With
        Numbers_dt.Rows(rowNumber).BeginEdit()
        Numbers_dt.Rows(rowNumber).Item("i_DDLItemIndex") = selectedIndex
        Numbers_dt.Rows(rowNumber).Item("u_DDLItemValue") = selectedValue
        Numbers_dt.Rows(rowNumber).EndEdit()
        Numbers_dt.Rows(rowNumber).AcceptChanges()
        DDLControlIndex_txtbx.Text = rowNumber.ToString()
        DDLItemIndex_txtbx.Text = Numbers_dt.Rows(rowNumber).Item("i_DDLItemIndex")
        DDLItemValue_txtbx.Text = Numbers_dt.Rows(rowNumber).Item("u_DDLItemValue")
        Page1_gv.DataBind()
    End Sub
    Protected Sub Page1_btn_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Div1_btn.Click
        Div1_div.Visible = False
        Div2_div.Visible = True
    End Sub
#End Region
#Region " Div 2 "
    Protected Sub Page2_div_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Div2_div.Load
        Div2_gv.DataSource = Numbers_dt
        Div2_gv.DataBind()
    End Sub
    Protected Sub Div2_btn_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Div2_btn.Click
        Div1_div.Visible = True
        Div2_div.Visible = False
    End Sub
#End Region
End Class
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top