[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Using user input to affect page layout on postback

Posted on 2005-04-05
45
Medium Priority
?
540 Views
Last Modified: 2012-08-13
Ok, that was not the most descriptive title, but my question is kind of specific and I couldn't sum it all up in one line.  Here's my problem...

I have a page which contains a number of dynamically generated datagrids.  Each datagrid contains rows of data for a group of people... each row representing a person in that group.  The number of groups, and hence the number of datagrids, depends on data stored in a database.  So, on Page_Load, I go to the database, determine the number of groups, create the datagrids, populate them, and then add them to a placeholder object which is declared in my aspx page.  This works fine.  I'm running into trouble when I try to alter this data based on user input.  One of the columns in the datagrid is a DropDownList which contains the group numbers of the groups on the page.  So, if I have 3 group datagrids on the page, the DropDowns contain the numbers 1, 2, and 3.  Each of these defaults to its group number... so, the "group 1" dropdowns have '1' selected, the "group 2" dropdowns have '2' selected, etc.  Now, I want to have a user be able to move people to different groups by changing their dropdown value to a different group number and the clicking a submit button.  When the page is submitted, I want to update the database for the people with altered dropdowns and then reload the page off the new database data.  This, however, seems to be easier said than done.  When I click submit, the original data is first loaded and THEN the button click method is called.  In the button click method I am determining which dropdowns were changed and updating the database accordingly, but this doesn’t really help since the page has already rendered the old data.  Furthermore, even if I could get the buttonclick method to execute first, it wouldn’t work because I need to access the datagrids to get at the dropdowns… and the datagrids aren’t created until after Page_Load is called.  So I guess my questions are these:

Can I collect the changed dropdown data on the client-side, pass it to the server on submit, alter the database BEFORE Page_Load, and then render the page?

Or, is there some other preferred way of handling this type of situation?

Please help shed some light on this for me!
0
Comment
Question by:smooga
  • 18
  • 16
  • 9
  • +1
45 Comments
 
LVL 4

Expert Comment

by:Kittrick
ID: 13712384
Yeah, it definitely sounds like a postback problem.

What does your Page_Load() look like??

 Do you have something similar to the code:

Sub Page_Load(sender as Object, e as EventArgs)

If Not Page.IsPostBack

myfunction()
End If

End Sub

I'm thinking you have your Sub call that contains the binding of your grids is not in the If Not Page.IsPostBack section. Although, I could be wrong obviously as I'm taking a complete stab in the dark.

Kittrick
0
 

Author Comment

by:smooga
ID: 13712699
Well, I had put in the !IsPostBack condition (using C#), but since I'm creating all of the grids dynamically in the Page_Load method and then adding them to a placeholder, if I surround that code with "if (!IsPostBack ) {...}", the page just comes back blank after the submit.  None of the grids are created and I cannot access the dropdowns (which are also not created) to determine what the user changed.
0
 
LVL 4

Expert Comment

by:Kittrick
ID: 13713068
hmmm...I still think it's definitely a postback problem, did you try the code if it is postback??

could you post your code?? I can read both vb.net and C#.

Kittrick
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

Author Comment

by:smooga
ID: 13713560
"did you try the code if it is postback"
I'm not sure what you mean.  Like I said, when I have the !IsPostBack condition, the datagrids are not created on postback.  Am I msunderstanding what you're asking?  

Unfortunately, I cannot post my code at the moment.  I'm no loger in the office, and the code that I zipped and emailed home was somehow corrupted.  I can post some simple pseudocode for now though...

Page_Load ()
{
    CreateGrids();
}

CreateGrids()
{
    // Connect to the database and get the data
    // Create the datagrids and bind to the data
    // Add the datagrids to the PlaceHolder object in the .aspx page
}

OnDataBind()
{
    // Create dropdownlists and add them to the datagrid
}

OnButtonClick()
{
    // Access the dropdownlists in the datagrids and determine if the selectedindex has changed
    // If so, update the database
}


The OnDataBind method is called for each datagrid and this is how I'm adding my dropdownlists.  This works correctly.  
When I surround the call to CreateGrids() with the !IsPostBack condition, the grids are only created on the initial page load.  When the page loads from a submit button click, CreateGrids is never called and they are never created.  This is the behavior I would expect.  Am I missing something here?  Should my code be laid out differently?
0
 
LVL 12

Expert Comment

by:laotzi2000
ID: 13714095
My suggestion:
Move calling CreateGrids() to Page_Prerender event handler
And in OnButtonClick you can access your datagrids from PlaceHolder1.Controls.
Iterate through them and compare their values to those in the database,
if something changed, modify the database.

After OnButtonClick executes, Page_Prerender will execute
CreateGrids and recreate those datagrids.

0
 

Author Comment

by:smooga
ID: 13716344
So let me make sure I understad how ASP.NET works in this scenario...

When the page initially loads, the grids will be created for the first time.  When a user clicks the button to submit, a request is made back to the server.  Page_Load is called and then OnButtonClick is called.  When OnButtonClick is called, it has access to the controls that were originally placed in the PlaceHolder control?  How is it possible that those controls still exist on the return to the server?  Are they persisted through the viewstate?

I'm headed to the office now.  Will try this out first thing.  Thanks
0
 
LVL 12

Expert Comment

by:laotzi2000
ID: 13716397
yes, even dynamically created controls will be kept in viewstate.

You can try it out by creating a simple control and add it to the page,
then you can do a postback(such as click a button), you will see the control
will still be there.
0
 

Author Comment

by:smooga
ID: 13717204
Ok, I've changed the code as you suggested, but it's still not working.  The initial page load works fine, but when I click submit, the request is made to the server, OnButtonClick is called, it looks in the PlaceHolder control for the datagrids, but the PlaceHolder is empty.  It doesn't seem to be retaining the PlaceHolder/Datagrid data in the viewstate... even though I explicitly set EnableViewState=true for the PlaceHolder and DataGrids.  This is how my code is laid out now:

Page_Prerender()
{
    CreateGrids();
}

CreateGrids()
{
    // Connect to the database and get the data
    // Create the datagrids and bind to the data
    // Add the datagrids to the PlaceHolder object in the .aspx page
}

OnDataBind()
{
    // Create dropdownlists and add them to the datagrid
}

OnButtonClick()
{
    // Access the dropdownlists in the datagrids via the PlaceHolder control and determine if the selectedindex has changed
    // If so, update the database
}
0
 
LVL 12

Expert Comment

by:laotzi2000
ID: 13717313
My fault, I made a mistake while testing.

I think dynamically generated controls are not preserved in postback.
0
 

Author Comment

by:smooga
ID: 13717378
I must not understand viewstate and postback fully then... here's a test page:

private void Page_Load(object sender, System.EventArgs e)
{
     this.EnableViewState = true;
     
     if ( !IsPostBack ) {
      myLabel = new Label();
      myLabel .Text = "Testing postback!";
      myPlaceholder.Controls.Add( myLabel );
     }
}

On postback the label will not be created... but my understanding of what laotzi2000 said above is that the label should still be loaded and displayed from the viewstate.
0
 

Author Comment

by:smooga
ID: 13717399
Ahhh... I didn't see your last post before I posted mine.

Ok, so if dynamically created controls are not preserved in postback, how do we handle this situation??
0
 
LVL 12

Expert Comment

by:laotzi2000
ID: 13717553
I think you can write some client side script to record what changes have
been made and store it in a hidden field on the page.
On postback, read from this hidden field and compare it with the database.
0
 
LVL 23

Expert Comment

by:b1xml2
ID: 13717557
smooga,

you have to understand about dynamic controls.

1. They have to be created and added to the page tree when the Page's Init method fires

#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
      //
      // CODEGEN: This call is required by the ASP.NET Web Form Designer.
      //
      InitializeComponent();
      base.OnInit(e);
}

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{    
      this.Load += new System.EventHandler(this.Page_Load);
      this.Init += new System.EventHandler(this.Page_Init);

}
#endregion

private void Page_Init(object sender,EventArgs e)
{
      /// add your controls to the page hierarchy
      /// view state cannot be accessed now
}

private void Page_Load(object sender,EventArgs e)
{
      /// you can access viewstate
}
0
 

Author Comment

by:smooga
ID: 13717561
So I'm thinking along the lines of my original question again... collect the changed dropdown values on the client-side using javascript, stash them in a hidden field, post to the server, pick up that data in OnButtonClick and update the database.  Maybe not the most elegant/pure-.NET way, but it should work.  Stay tuned
0
 

Author Comment

by:smooga
ID: 13717611
I keep posting before reading the other posts...

laotzi2000, exactly what I was thinking :)

b1xml2, can you clarify something for me?  What does moving that code to Page_Init achieve?  Does it allow their viewstate to persist on postback?
0
 
LVL 23

Expert Comment

by:b1xml2
ID: 13717641
2. the dynamic controls you add must be given fixed IDs upfront, so that there is no mixup during postbacks.

3. Now comes the million dollar question: If we depend on user interaction and viewstate in the first place to determine what controls to add, well you're stuffed.

SITUATION A
=========
1. Need to create controls immediately when the Init event fires.
2. Cannot access ViewState for user input

SITUATION B
=========
1. User input done
2. View State holds partial or all of information

SOLUTION
======
1. Move storage of information which determines the whys and hows of the dynamic control away from ViewState..
2. Alternative storage would be Session (Across pages so if the user presses control+N and the settings for MSIE is to reuse existing windows, you end up having 2 windows sharing the same session..yikes!!)
OR
3. Move storage of information to database or temp xml and set the keys inside hidden input. Request.Form collection is accessible and quite apart from ViewState.
OR
4. Store keys and write out classes that handle the control generation according to the keys..

0
 
LVL 23

Expert Comment

by:b1xml2
ID: 13717682
smooga... by adding controls inside Page_Init, it is as though they were written manually, so the viewstate will be persisted BEFORE the button's onclick event fires up...

It is a well known method, since the view state does not begin to be reconstituted until after the Init Event. If you write it in the Load Event, it will take some time to catch up whilst other events have already fired off
0
 
LVL 12

Expert Comment

by:laotzi2000
ID: 13717695
it's easy to store the controls created dynamically.
What's difficult is to construct a control from the web page with user
change.
0
 
LVL 12

Expert Comment

by:laotzi2000
ID: 13717900
b1xml2 is correct, though he is very clear on some point.

Dynamically created control's viewstate can be preserved if it is created in Page_Init

You can try this one:
   Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
         Dim c As New TextBox
        PlaceHolder1.Controls.Add(c)
    End Sub

On postback, the user input in Textbox is preserved and is available on server side.
0
 
LVL 12

Expert Comment

by:laotzi2000
ID: 13718009
I'm still playing around with it and I found b1xml2 not correct.
But I think I have found a solution with it.
0
 
LVL 12

Expert Comment

by:laotzi2000
ID: 13718121
I found out that if you create your controls dynamically in or before Page_Load event handler,
your controls will be automatically populated from data in viewstate right after Page_Load.

So if you create your dropdownlists in or before Page_Load, it will contain user input.

My suggestion:
Create Datagrid in Page_Load
Create empty Dropdownlists for DataGrids in Page_Load too
In OnDataItemBound, set proper values for dropdownlist if it is not postback

Then, in your button_click function, you can get the user selection from the dropdownlists
0
 

Author Comment

by:smooga
ID: 13718202
laotzi, I'm going to try the client-side scripting solution in the meantime.  Look forward to hearing other solutions though.

b1xml2, thanks for all the info... your solutions might be a little involved for my needs, but they're definitely informative.  Thanks.

Once I finally get this problem licked, I'll split the points between both of you since you both had valuable input.  Sound good?
0
 

Author Comment

by:smooga
ID: 13718224
laotzi2000, trying... I think the key might be to put the !IsPostBack only in OnDataItemBound.  Good call.  brb...
0
 

Author Comment

by:smooga
ID: 13718352
Ok, no, I don't think that's possible.  How can I create the dropdownlists before OnItemDataBound?  They are currently being created/inserted dynamically as each row of the datagrid is created.  I suppose I could create a custom DropDownList TemplateColumn class, but that seems like a bit too much work for this problem :)  Plus, I am creating a number of other objects for other columns in the OnItemDataBound method... don't see how to avoid creating them here.
0
 
LVL 12

Expert Comment

by:laotzi2000
ID: 13718440
When do you call the datagrid.databind in your code? In Page_Load?
And is onItemDataBound execute before Page_Load ends?(debug it to find out)
If that's case, it should be OK to put those code in OnItemDataBound.

Another note: I think you should assign a unique id manually for each dropdownlist control
(the primary key of the record must be a perfect choice)
so after Page_Load, it can find proper viewstate data for the dropdownlist control. I think
maybe this is really what the problem is.
0
 
LVL 23

Expert Comment

by:b1xml2
ID: 13718586
consider this:
<%@ Page language="c#" Codebehind="DynamicControls.aspx.cs" AutoEventWireup="false" Inherits="b1xml2.ExpertsExchange.CSharp.April.DynamicControls" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" > 
<html>
<head>
<title>DynamicControls</title>
<meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
<meta name="CODE_LANGUAGE" Content="C#">
<meta name=vs_defaultClientScript content="JavaScript">
<meta name=vs_targetSchema content="http://schemas.microsoft.com/intellisense/ie5">
<script language="javascript">
function persistValue(value)
{
      var el = document.forms[0]["Stage"];
      if (el) el.value = "" + value;
      alert(el.value);
}

</script>
</head>
<body MS_POSITIONING="FlowLayout">
<form id="Form1" method="post" runat="server">
<asp:PlaceHolder ID="holder" Runat="server"></asp:PlaceHolder>
</form>
</body>
</html>
0
 
LVL 23

Expert Comment

by:b1xml2
ID: 13718590
and then this:
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace b1xml2.ExpertsExchange.CSharp.April
{
      /// <summary>
      /// Summary description for DynamicControls.
      /// </summary>
      public class DynamicControls : System.Web.UI.Page
      {
            protected System.Web.UI.WebControls.PlaceHolder holder;
            protected DropDownList country;
            protected DropDownList state;
            protected LinkButton submit;

            private StageList stage = StageList.None;
      
            private void Page_Init(object sender, EventArgs e)
            {
                  if (CompareEnum(Stage,StageList.Country))
                  {
                        AddCountry();      
                        
                  }
                  
                  if (CompareEnum(Stage,StageList.State))
                  {
                        AddState();
                        
                  }

                  if (CompareEnum(Stage,StageList.Submit))
                  {
                        AddSubmit();
                        
                  }

                  
            }

            private void AddCountry()
            {
                  country = new DropDownList();
                  country.ID = "country";
                  country.Attributes["onchange"] = string.Format("persistValue(this.selectedIndex == 0 ? {0} : {1});",
                        (int)StageList.FirstStage,
                        (int)StageList.SecondStage);
                  country.DataTextField = "Value";
                  country.DataValueField = "Key";
                  holder.Controls.Add(ParseControl("<div><b>Country</b>"));
                  holder.Controls.Add(country);
                  holder.Controls.Add(ParseControl("</div>"));
                  country.SelectedIndexChanged += new EventHandler(country_SelectedIndexChanged);
                  country.AutoPostBack = true;

            }

            private void AddState()
            {
                  state = new DropDownList();
                  state.ID = "state";
                  state.Attributes["onchange"] =  string.Format("persistValue(this.selectedIndex == 0 ? {0} : {1});",
                        (int)StageList.SecondStage,
                        (int)StageList.ThirdStage);
                  state.DataTextField = "Value";
                  state.DataValueField = "Key";
                  holder.Controls.Add(ParseControl("<div><b>State</b>"));
                  holder.Controls.Add(state);
                  holder.Controls.Add(ParseControl("</div>"));
                  state.SelectedIndexChanged += new EventHandler(state_SelectedIndexChanged);
                  state.AutoPostBack = true;
                              
            }

            private void AddSubmit()
            {
                  submit = new LinkButton();
                  submit.ID = "submit";
                  submit.Text = "Submit Selection";
                  holder.Controls.Add(submit);
                  submit.Click += new EventHandler(submit_Click);
            }

            private bool CompareEnum(StageList composite,StageList value)
            {
                  return ((composite & value) == value);
            }


            private StageList Stage
            {
                  get
                  {
                        if (stage == StageList.None)
                        {
                              int value = Request.Form["Stage"] == null ? 1 : int.Parse(Request.Form["Stage"]);
                              stage = (StageList)value;
                        }
                        return  stage;                  
                  }
                  set
                  {
                        stage = value;
                  }
            }

            private void Page_Load(object sender, System.EventArgs e)
            {
                  if (! Page.IsPostBack)
                  {
                        PopulateCountries();
                        
                  }
                  SetStage();
                  
                  
            }

            private void PopulateCountries()
            {
                  SortedList list = new SortedList();
                  list["US"] = "United States";
                  list["UK"] = "United Kingdom";
                  
                  this.country.DataSource = list;
                  this.country.DataBind();
                  this.country.Items.Insert(0,"Please Select Country");
            }

            private void SetStage()
            {
                  Page.RegisterHiddenField("Stage",((int)Stage).ToString());
            }

            

            #region Web Form Designer generated code
            override protected void OnInit(EventArgs e)
            {
                  //
                  // CODEGEN: This call is required by the ASP.NET Web Form Designer.
                  //
                  InitializeComponent();
                  base.OnInit(e);
            }
            
            /// <summary>
            /// Required method for Designer support - do not modify
            /// the contents of this method with the code editor.
            /// </summary>
            private void InitializeComponent()
            {    
                  this.Load += new System.EventHandler(this.Page_Load);
                  this.Init += new EventHandler(Page_Init);
                  

            }
            #endregion

            

            private void country_SelectedIndexChanged(object sender, EventArgs e)
            {
                  if (this.country.SelectedIndex > 0)
                  {
                        if (this.state == null)
                        {
                              AddState();
                              this.Stage = StageList.SecondStage;
                        }
                        SortedList sl = new SortedList();
                        switch (this.country.SelectedValue)
                        {
                              case "UK":
                                    sl["WL"] = "Wales";
                                    sl["EN"] = "England";
                                    sl["SC"] = "Scotland";
                              break;
                              case "US":
                                    sl["NY"] = "New York";
                                    sl["TX"] = "Texas";
                              break;
                        }

                        state.DataSource = sl;
                        state.DataBind();
                        state.Items.Insert(0,"Please Select State");
                  }
                  else
                  {
                        this.Stage = StageList.FirstStage;
                  }
                  SetStage();
            }

            private void state_SelectedIndexChanged(object sender, EventArgs e)
            {
                  if (this.state.SelectedIndex > 0)
                  {
                        if (this.submit == null)
                        {
                              AddSubmit();
                              this.Stage = StageList.ThirdStage;
                        }
                  }
                  else
                  {
                        this.Stage = StageList.SecondStage;
                  }
                  SetStage();
            }

            private void submit_Click(object sender, EventArgs e)
            {
                  Response.Write(string.Format("<div>Country Is {0}</div>\n<div>State Is {1}</div>",country.SelectedValue,state.SelectedValue));
            }

      }

      [Flags]
      public enum StageList : int
      {
            None = 0,
            Country = 1,
            State = 2,
            Submit = 4,
            FirstStage = Country,
            SecondStage = Country | State,
            ThirdStage = Country | State | Submit
      }
}
0
 
LVL 23

Expert Comment

by:b1xml2
ID: 13718598
you will see the dynamic creation of web controls and the application of the viewstate to it before the appropriate web control events are fired off. that;s how you deal with dynamic web controls
0
 
LVL 23

Expert Comment

by:b1xml2
ID: 13718621
comment out the alert if you dont want to see what value is being set...
but only by understanding the viewstate and the nature of the postbacks and adding controls the way shown in the snippet, can you successfully use dynamic controls

HTH
0
 

Author Comment

by:smooga
ID: 13718656
Well, as far as the ID is concerned, I think that might be a problem.  Even though I specify an ID for the dropdowns (using the primary key as suggested), since they are in a datagrid, .NET is prepending "_ctl0__ctl0", "_ctl0__ctl1", "_ctl0__ctl2", etc.  I don't know if this is causing a problem, but the code still doesn't work.  

Initial load works fine.  On submit, the grids are created but the code in OnItemDataBound does not execute because of the !IsPostBack condition.  Then the OnButtonClick executes.  It looks inside the grids and throws an exception:

foreach ( DataGridItem row in dg.Items ) { // each row of the DataGrid
    DropDownList ddl = (DropDownList) row.FindControl( "groupDDL" ).Controls[ 0 ];  <-- fails here because it can't find the dropdown

    ......
}

Although I'm really curious about getting this to work the "right" way, I think I'm going to have to go with the client-side scripting method.  Spending way too much time on this and I have deadlines to worry about.
0
 

Author Comment

by:smooga
ID: 13718688
Thanks b1xml2.  Once again my curiostiy gets the better of me... will try this code out despite having just said I'm spending too much time on this problem :)
0
 
LVL 12

Expert Comment

by:laotzi2000
ID: 13718704
On more try:

remember that whether it is postback or not, you should create those dropdownlists,
so you should not put the code inside !Ispostback.
0
 
LVL 12

Expert Comment

by:laotzi2000
ID: 13718712
I'm pretty positive that it will work.

Cheers up.
0
 
LVL 23

Expert Comment

by:b1xml2
ID: 13718716
the ids here will not relate to the child controls...so you don;t have to worry about that...you just have to ensure that your datagrid has an id,
show us a snippet (small pls) and we'll get a working code for you.

0
 

Author Comment

by:smooga
ID: 13718841
Well, I got it working by placing the CreateGrids code in Page_Init and giving a unique ID to the grids, but it only works if I don't use the !IsPostBack condition.  This means that on postback, the grids are being created from the database data, then onButtonClick updates the database, then the grids are recreated from the database data.  Three database hits.  Not really what I'm looking for.

I can't really post a small snippet of my code... it's pretty long.  Let me try to edit it down to just the very basics.  hold on...
0
 
LVL 12

Expert Comment

by:laotzi2000
ID: 13718940
I think even if you recreate the datagrids from the database in Page_Init,
it will still get viewstate data after Page_Load
Your data from the database will be lost

I have an example here:
in Page_Load
      Dim c As New TextBox
        c.Text = "haha"
        PlaceHolder1.Controls.Add(c)

you'll see that even though you set the text of the textbox to haha everytime in Page_Load,
only the user input will preserve.
0
 
LVL 12

Expert Comment

by:laotzi2000
ID: 13718993
So you can create the grids in Page_Init or Page_Load
It will get Populated from viewstate data after Page_Load
Then you modify the database according to these data in OnButtonClick
Then you can recreate those grids according to the database in Page_Prerender.

Quite complex.
0
 

Author Comment

by:smooga
ID: 13719082
Ok, here's a very edited version... not putting any !IsPostBack condition in.

private void Page_Init(object sender, EventArgs e)
{
    LoadGrids();
}

private LoadGrids() { ... } // this method calls CreateGrids for each group in the database

private void CreateGrids( DataView groupView )
{
        DataGrid groupGrid = new DataGrid();
      int groupNum = (int) groupView[ 0 ][ "Group_Number" ];
      groupGrid.ID = "groupGrid_" + groupNum;
                        
      // Set grid properties.......
      groupGrid.AutoGenerateColumns  = false;
      groupGrid.EnableViewState = true;
      groupGrid.DataSource = groupView;
      groupGrid.ItemDataBound += new DataGridItemEventHandler( OnItemDataBound );

        BoundColumn name = new BoundColumn();
      name.DataTextField = "Full_Name";

        TemplateColumn assignedGroup = new TemplateColumn();
       
      groupGrid.Columns.Add( name );
        groupGrid.Columns.Add( assignedGroup );

      groupGrid.DataBind();
      placeholder.Controls.Add( groupGrid );
}

private void OnItemDataBound( Object sender, DataGridItemEventArgs e )
{
      DataView groupView = (DataView) ((DataGrid) sender).DataSource;

      if ( e.Item.ItemType != ListItemType.Header && e.Item.ItemType != ListItemType.Footer ) {
            DropDownList ddl = new DropDownList();
            
            /*
            code to populate dropdownlist from other database data.
            */

            e.Item.Cells[ 1 ].ID = "groupDDL";
            e.Item.Cells[ 1 ].Controls.Add( ddl );
      }
}

private void UpdateButton_Click( object sender, System.Web.UI.ImageClickEventArgs e )
{
      string sqlStr = "";
                  
      foreach ( object aControl in placeholder.Controls ) {
            if ( aControl.GetType() == typeof( DataGrid )) {      // each DataGrid
                  DataGrid dg = (DataGrid) aControl;
                  foreach ( DataGridItem row in dg.Items ) {      // each row of current DataGrid
                        DropDownList ddl = (DropDownList) row.FindControl( "groupDDL" ).Controls[ 0 ];
                        // if selected index was changed, create sqlstr string
                  }
            }
      }
                  
      if ( sqlStr.Length > 0 ) {
            // update database
      }
}
0
 

Author Comment

by:smooga
ID: 13719220
"So you can create the grids in Page_Init or Page_Load
It will get Populated from viewstate data after Page_Load
Then you modify the database according to these data in OnButtonClick
Then you can recreate those grids according to the database in Page_Prerender."

But I would still be hitting the database before the viewstate loaded, right?  In order to create the grids without using the viewstate, I need to look up data in the database.  I'm trying to avoid hitting the database, overwriting that data with the viewstate, updating the database based on user input, and then hitting it again to recreate the controls based on the newly updated database.  Why load data from the database if it's only going to be immediately overwritten by the viewstate data?  Unless there's no other way to do it.  In which case, it would be more elegant to use client-side scripting to post the dropdown data to the server and then create the grids only once in Prerender.
0
 
LVL 12

Accepted Solution

by:
laotzi2000 earned 1000 total points
ID: 13719399
The reason is that asp .net will populate controls in two phases.

First, after Page_Init, asp.net will create all those static controls and populate them from data in viewstate.
Then, after Page_Load, asp.net will populate all dynamically created controls from data in viewstate again.
But in order to make it able to get data from viewstate, the controls must be created first, or their viewstate
information is just ignored.
That's why you need to create those grids first from database so they can receive viewstate data.
0
 
LVL 23

Assisted Solution

by:b1xml2
b1xml2 earned 1000 total points
ID: 13719600
you can kill 2 birds with one stone

<asp:Repeater ...>
<ItemTemplate>
<div><%# DataBinder.Eval(Container.DataItem,"GroupName")%></div>
<asp:DataGrid Id="dgUser" ...>

</asp:DataGrid>
</ItemTemplate>
</asp:Repeater>

1. Hook up into the ItemDataBound event of the repeater and bind data to the grid from there after getting the reference.
2. Hook up the grid's ItemDataBound event and populate any TemplateColumn's controls
3. You cannot use <%# %> inside the DataGrid... So you have to manually populate the controls inside the TemplateColumns.
4. This will allow data to be persisted across postbacks.
0
 

Author Comment

by:smooga
ID: 13719719
b1xml,
    Ahh, I see what you're saying.  The Repeater will automatically persist the data unlike the Placeholder, right?  And I get the added benefit of having it spit out my multiple datagrids.  Terrific!  I think this is the right solution.

laotzi,
    Thanks for the link.  I'm going to use b1xml's solution though since it "kills 2 birds with one stone".

I want to give you both points... you were both more than helpful.  Is there a way to give 500 to both of you?  If not, are you ok with 250 each?
0
 
LVL 12

Expert Comment

by:laotzi2000
ID: 13719830
It doesn't matter.
I've learned quite a bit too. :)
0
 

Author Comment

by:smooga
ID: 13719975
Well, I tried to give you both 500.  Let me know if it worked.

Thanks guys.  Above and beyond :)
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

ASP.Net to Oracle Connectivity Recently I had to develop an ASP.NET application connecting to an Oracle database.As I am doing it first time ,I had to solve several problems. This article will help to such developers  to develop an ASP.NET client…
Introduction This article shows how to use the open source plupload control to upload multiple images. The images are resized on the client side before uploading and the upload is done in chunks. Background I had to provide a way for user…
Please read the paragraph below before following the instructions in the video — there are important caveats in the paragraph that I did not mention in the video. If your PaperPort 12 or PaperPort 14 is failing to start, or crashing, or hanging, …
Despite its rising prevalence in the business world, "the cloud" is still misunderstood. Some companies still believe common misconceptions about lack of security in cloud solutions and many misuses of cloud storage options still occur every day. …
Suggested Courses

829 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