Hi All,<BR><BR>I have a problem that probably takes longer to explain than to solve, so I hope someone has the patience to read the whole posting! I have included all the relevant code below, and simplified it down as much as I can. <BR><BR><BR>THE DESIGN AND THE PROBLEM <BR><BR>Basically I have a DataList bound to a DataTable. When the page PreRenders, new rows are added to the DataTable, and the DataList is rebound to it, so the DataList SHOULD display the new data automatically on Page_PreRender. This is what I want. <BR><BR>But in fact these new rows are not displayed until a button is pressed (I DON'T want to have to wait for the button click). The strange thing is that pressing the button calls exactly the same routine that Page_PreRender calls, so I have no idea why clicking the button causes the subroutine to work, while the same subroutine called from Page_PreRender apparently doesn't work!<BR><BR>In the actual code the DataList is inside a UserControl, which is within another UserControl, which is inside a DataGrid (!), but the basic principle - and basic problem - is as described above. Now I'll try to explain how the page is structured, so no one has to spend too much time working out my code.<BR><BR><BR>THE CODE EXPLAINED<BR><BR>There is a main aspx page ("MainPage.aspx") which holds a UserControl ("MainUserControl.ascx") inside a DataGrid. Within this MainUserControl.ascx there are two further UserControls, one on the left hand side of a table ("SubUserControl_LHS.ascx") and one on the right ("SubUserControl_RHS.ascx"). The left hand UserControl has a DropDownList and a LinkButton, the right hand UserControl has a DataList within it.<BR><BR>The page is part of a forum site, and its purpose is to display and allow editing of a list of Author(s) of a given message (messages to this forum CAN have multiple authors). The page will first pull the author(s) of a particular message out of an Access database, and display these names in the DataList in SubUserControl_RHS.ascx. <BR><BR>The page user will then be able to edit this "Authors" list in two ways:<BR><BR> 1) by clicking on a displayed name, that name is REMOVED from the list of authors (this is handled by Sub myDataList_DeleteCommand within SubUserControl_RHS.ascx)<BR> <BR> 2) the user can ADD to the list of Authors by selecting from the DropDownList and clicking the LinkButton in SubUserControl_LHS.ascx.<BR><BR>However (1) and (2) these parts of the page work fine - I have just included them to help understand the code. It is the initial display of author(s) pulled from the Database which is NOT working.<BR><BR>To simplify things, I have replaced the Access query with a simple fixed ArrayList in MainPage.aspx:<BR> myAL.Add("Bob")<BR> myAL.Add("Jimmy")<BR> myAL.Add("Eric")<BR>but this simplified code still displays the same problem. So imagine that "Bob", "Jimmy" and "Eric" are the three authors of the current message that have been pulled from the database.<BR><BR>The Public Sub "AddPerson" in SubUserControl_RHS.ascx controls the adding of these authors to the DataTable, and then DataBinding this DataTable to the DataList. When called, this subroutine checks that the passed name is not already in a DataTable (which itself is stored in the ViewState), and if the name is not a duplicate, it adds a new row to a DataTable and then DataBinds the DataTable.<BR><BR><BR>So, when MainPage.aspx first loads, what SHOULD happen is this: <BR><BR>a) MainPage.aspx's PreRender finds the MainUserControl in the DataGrid and passes the Bob/Jimmy/Eric ArrayList to the DisplayNames subroutine in MainUserControl.ascx<BR><BR>b) DisplayNames loops through this little ArrayList, each time passing a name to the AddPerson subroutine of SubUserControl_RHS.ascx<BR><BR>c) AddTable pulls a pre-built DataTable out of the ViewState, checks that the name it has received is not a duplicate name, adds the name to a new row of the DataTable, puts the amended DataTable back into the ViewState, and binds the DataList to the amended DataTable.<BR><BR>d) The DataList displays the added name(s)<BR><BR><BR>**************** THE PROBLEM *********************<BR>This last step (d) IS WHERE THE PROBLEM IS - the names are NOT displayed on Page_PreRender. <BR> <BR><BR>In fact, the DataList displays absolutely nothing on Page_PreRender. But then - oddly - if I select a name from the DropDownList in SubUserControl_LHS.ascx, and click the "Add User" button, the names Bob, Jimmy and Eric pop out of the ether and show up in the DataList, along with the name just selected from the DropDownList!<BR><BR>So it seems most of the code HAS worked! The names Bob, Jimmy and Eric seem to be in the DataTable, but for some reason are NOT being displayed in the DataList on Page_PreRender, but only when the LinkButton is clicked (which is too late)<BR><BR>Congratulations for reading this far! Now you understand the problem, I hope you can tell me what's going on and how to fix it!<BR><BR>Thanks in advance,<BR><BR>Cheers,<BR><BR>JON<BR><BR><BR><BR><BR><BR><BR><BR>++++++++++++++++++++++++++<BR>MainPage.aspx<BR>++++++++++++++++++++++++++<BR><BR><BR><BR><BR><%@ Page Language="VB" Trace="true" Debug="true" %><BR><%@ Import Namespace="System.Data" %><BR><%@ Import Namespace="System.Data.Oledb" %><BR><BR><%@ Register TagPrefix="UserControl" TagName="Article" src=http://aspmessageboard.com/archive/index.php/"MainUserControl.ascx" %><BR><BR><BR><script language="VB" runat="server"><BR><BR><BR>Dim myAL As New ArrayList()<BR><BR>Sub Page_Load(sender as object, e as eventargs)<BR><BR> '*** dummy HashTable just to give the dg a shape!<BR> Dim myHT As New Hashtable()<BR> myHT.Add("ABC", "XYZ")<BR> dg.DataSource = myHT<BR> <BR> '*******************************************<BR> '*** HERE IS THE PROBLEM<BR> '*** These names should appear automatically<BR> '*** in the DataList in SubUserControl_RHS.ascx<BR> '*** when this MainPage.aspx PreRenders<BR> '*** BUT THEY DON'T!<BR> '*******************************************<BR> myAL.Add("Bob")<BR> myAL.Add("Jimmy")<BR> myAL.Add("Eric")<BR><BR><BR>If Not Page.IsPostBack Then<BR> dg.EditItemIndex = 0 '*** DataGrid opens in Edit Mode<BR> dg.Databind()<BR> End If<BR>End Sub<BR><BR><BR><BR>Sub Page_PreRender(sender As Object, e As EventArgs)<BR>'*** The UserControl is not found if I do this in Page_Load<BR><BR> Dim item as DataGridItem<BR> For Each item In dg.Items<BR> If (Item.ItemType = ListItemType.EditItem) then<BR> If Not Page.IsPostBack then<BR> Dim ucArticle as AddArticleTemplate = Item.FindControl("ucArticle")<BR> '*** THE DISPLAYNAMES SUB IS CALLED HERE ****<BR> ucArticle.DisplayNames(myAL) <BR> end if<BR> end if<BR> Next item<BR><BR>end sub<BR><BR><BR></script> <BR><BR><html><BR><form runat="server"><BR><BR><asp
ataGrid id="dg" runat="server" AutoGenerateColumns="False"><BR><Columns><BR><asp:TemplateColumn><BR> <EditItemTemplate><BR> <UserControl:Article id="ucArticle" runat="server" /><BR> </EditItemTemplate><BR></asp:TemplateColumn><BR></Columns><BR></asp:dataGrid><BR><BR></form> <BR></body><BR></html><BR><BR><BR><BR><BR><BR><BR><BR>++++++++++++++++++++++++++<BR>MainUserControl.ascx<BR>++++++++++++++++++++++++++<BR><BR><BR><BR><%@ Control Language="VB" ClassName="AddArticleTemplate" %><BR><%@ Import Namespace="System.Data" %><BR><%@ Import Namespace="System.Data.Oledb" %><BR><BR><%@ Register TagPrefix="LHS" TagName="UserControl" src="SubUserControl_LHS.ascxx" %><BR><%@ Register TagPrefix="RHS" TagName="UserControl" src="SubUserControl_RHS.ascx" %><BR><BR><BR><script language="VB" runat="server"><BR><BR><BR>Sub Page_Load(obj as object, e as EventArgs)<BR> If not Page.IsPostBack<BR> DataBind() <BR> end if<BR>end sub<BR><BR> <BR>Protected Overrides Function OnBubbleEvent(obj As Object, e As EventArgs) As Boolean<BR> '*** to detect bubble event in SubUserControl_LHS.ascx<BR> '*** and add selected person to DataTable in SubUserControl_RHS.ascx<BR> if obj.Text = "Add Author" then<BR> RHSUserControl.AddPerson(LHSUserControl.SelectedPe rsonName, LHSUserControl.SelectedPersonValue)<BR> end if<BR> Return True<BR>End Function<BR><BR><BR>'*** THIS ROUTINE SHOULD DISPLAY THE NAMES ***<BR>Public Sub DisplayNames(objExistingMessageDetails as ArrayList)<BR> Dim TempAL as ArrayList = objExistingMessageDetails<BR> Dim myEnumerator As System.Collections.IEnumerator = TempAL.GetEnumerator()<BR> While myEnumerator.MoveNext()<BR> RHSUserControl.AddPerson(myEnumerator.Current, 1)<BR> End While<BR>End Sub<BR><BR></script><BR><BR><BR><BR><asp:Table runat="server"><BR> <asp:TableRow><BR> <asp:TableCell VerticalAlign="top" width="50%"><BR> <LHS:UserControl runat="server" id="LHSUserControl" /><BR> </asp:TableCell><asp:TableCell width="50%"><BR> <RHS:UserControl runat="server" id="RHSUserControl" /><BR> </asp:TableCell><BR> </asp:TableRow> <BR></asp:Table><BR><BR><BR><BR><BR><BR><BR><BR><BR>++++++++++++++++++++++++++<BR>SubUserControl_RHS.ascx<BR>++++++++++++++++++++++++++<BR><BR><BR><BR><%@ Control Language="VB" %><BR><%@ Import Namespace="System.Data" %><BR><%@ Import Namespace="System.Data.Oledb" %><BR><BR><script language="VB" runat="server"><BR><BR>Dim objDatabase as new BusinessObjects.Database<BR>Dim ds as new DataSet()<BR>Dim myDataTable as DataTable<BR>Dim myColumn as DataColumn<BR>Dim myRow as DataRow<BR><BR><BR>Sub Page_Load(obj as object, e as eventargs)<BR><BR>objDatabase.ConnectionString = ConfigurationSettings.AppSettings("ConnectionString")<BR>objDatabase.DataSet = ds<BR><BR> If Not IsNothing(ViewState("PeopleToAdd")) then<BR> myDataList.DataSource = ViewState("PeopleToAdd")<BR> end if<BR><BR>If not Page.IsPostBack<BR> DataBind()<BR> <BR> '*** Set up the DataTable in ViewState ***<BR> myDataTable = new DataTable("PeopleToAdd")<BR> myColumn = myDataTable.Columns.Add("PersonID", System.Type.GetType("System.Int32"))<BR> myColumn.AllowDBNull = false<BR> myColumn = myDataTable.Columns.Add("Name", System.Type.GetType("System.String"))<BR> myColumn.AllowDBNull = false<BR> ViewState("PeopleToAdd") = myDataTable<BR><BR>end if <BR><BR>end sub<BR><BR><BR>'*** THE DATALIST IS ADDED TO HERE **************<BR>Public Sub AddPerson(SelectedPersonName as String, SelectedPersonValue as Integer) <BR>'*** adds to the DataTable "PeopleToAdd" in memory, holding the author(s) of the Item<BR><BR>'*** Pull the DataTable out of the ViewState<BR>myDataTable = ViewState("PeopleToAdd")<BR> <BR>'*** Check you aren't entering the same person twice<BR>If objDatabase.CheckForDuplicateValuesInDataTable(myD ataTable, "Name", SelectedPersonName) = true then<BR> lbDuplicate.Text = "Duplicate Value found! - no item added!"<BR>Else <BR>'*** Add the row to the DataTable<BR> myRow = myDataTable.NewRow()<BR> myRow("PersonID") = SelectedPersonValue<BR> myRow("Name") = SelectedPersonName<BR> myDataTable.Rows.Add(myRow)<BR> <BR>'*** Put everything back in the ViewState <BR> ViewState("PeopleToAdd") = myDataTable<BR> <BR>'*** Blank out any "duplicate found" error messages <BR> lbDuplicate.Text = ""<BR> <BR> myDataList.DataBind()<BR> <BR>End if<BR>End sub<BR><BR><BR><BR>Sub myDataList_DeleteCommand(obj as object, e as DataListCommandEventArgs)<BR> myDataTable = ViewState("PeopleToAdd")<BR> myDataTable.Rows.RemoveAt(e.Item.ItemIndex)<BR> ViewState("PeopleToAdd") = myDataTable<BR> myDataList.DataBind()<BR> lbDuplicate.Text = "" '*** Blank out any "duplicate found" error messages <BR>End sub<BR><BR><BR><BR>Public ReadOnly Property Authors As ArrayList<BR>Get<BR> myDataTable = ViewState("PeopleToAdd")<BR> dim tempArrayList as New ArrayList()<BR> dim tempRow as DataRow<BR> for each tempRow in myDataTable.Rows<BR> tempArrayList.Add(tempRow("PersonID"))<BR> next tempRow <BR> Return tempArrayList<BR>End Get<BR>End Property<BR><BR></script><BR><BR><b>Authors (click to delete):</b><BR><asp
ataList runat="server" <BR> id="myDataList" <BR> repeatlayout = "flow"<BR> repeatdirection = "horizontal"<BR> OnDeleteCommand = "myDataList_DeleteCommand"><BR><BR><ItemTemplate><BR> <asp:LinkButton runat="server" Text='<%# Container.DataItem("Name") %>' CommandName="Delete" /> ///<BR></ItemTemplate> <BR><BR></asp
ataList><BR><BR><asp:Label runat="server" id="lbDuplicate" /><BR><BR><BR><BR>++++++++++++++++++++++++++<BR>SubUserControl_LHS.ascx<BR>++++++++++++++++++++++++++<BR><BR><BR><%@ Control Language="VB" %><BR><%@ Import Namespace="System.Data" %><BR><%@ Import Namespace="System.Data.Oledb" %><BR><BR><BR><script language="VB" runat="server"><BR><BR>Dim objDatabase as new BusinessObjects.Database<BR>Dim ds as new DataSet()<BR><BR>Dim myDataTable as DataTable<BR>Dim myColumn as DataColumn<BR>Dim myRow as DataRow<BR><BR><BR>Sub Page_Load(obj as object, e as eventargs)<BR><BR> objDatabase.ConnectionString = ConfigurationSettings.AppSettings("ConnectionString")<BR> objDatabase.DataSet = ds<BR> ddDDL.DataSource = objDatabase.CreateDataTableDefaultView("tblPostedBy", "SELECT tblPeople.PersonID, tblPeople.FullName FROM tblPeople;")<BR> ddDDL.DataTextField = "People"<BR> ddDDL.DataValueField = "PersonID"<BR> <BR> If not Page.IsPostBack<BR> DataBind()<BR> end if <BR> <BR>end sub<BR><BR> <BR>Public ReadOnly Property SelectedPersonName As String<BR> Get<BR> Return ddDDL.SelectedItem.Text<BR> End Get<BR>End Property<BR><BR><BR>Public ReadOnly Property SelectedPersonValue As Integer<BR> Get<BR> Return ddDDL.SelectedItem.Value<BR> End Get<BR>End Property<BR><BR> <BR></script><BR><BR>Authors - choose from list:<BR><asp
ropDownList id="ddDDL" runat="server" /><BR><BR><asp:LinkButton runat="server" Text="Add Author" id="lbLinkButton" />Hi All,<BR><BR>I solved the problem eventually. In SubUserControl_RHS.ascx, I had to move the line: <BR><BR> myDataList.DataSource = ViewState("PeopleToAdd")<BR><BR>into the Page_Load If Not Page.IsPostBack subroutine, giving this:<BR><BR> <BR>If not Page.IsPostBack<BR> <BR> '*** Set up the DataTable in memory "PeopleToAdd" to hold the chosen People_As_Authors<BR> myDataTable = new DataTable("PeopleToAdd")<BR> myColumn = myDataTable.Columns.Add("PersonID", System.Type.GetType("System.Int32"))<BR> myColumn.AllowDBNull = false<BR> myColumn = myDataTable.Columns.Add("Name", System.Type.GetType("System.String"))<BR> myColumn.AllowDBNull = false<BR> ViewState("PeopleToAdd") = myDataTable<BR> myDataList.DataSource = ViewState("PeopleToAdd") '**** PUT THE LINE HERE INSTEAD!<BR> DataBind()<BR> <BR>end if <BR><BR><BR>Cheers,<BR><BR>JON



