Page 3 of 3 FirstFirst 123
Results 21 to 28 of 28

Thread: Dynamic ASP.Net web controls

  1. #21
    Join Date
    Dec 2002
    Posts
    500
    Rep Power
    0

    Default

    there is no need to do what you guys are doing.
    that is bad programming and you know it.

    all that said.

    A. if you want dynamic controls only add them after checking IsPostback property
    B. do not add them again if the form IsPosted back.
    C. set unique ids for the controls you use.
    D. design before code ( at least draw what you want to see on paper, link them with arrows for page loads and postbacks).

    if theres still a point to what you are doing, let me see the drawings and ill help you figure it out.
    Cultured in Aggression and Koding like a Warrior!!
    “Common sense is instinct. Enough of it is genius.” - George Bernard Shaw.
    "The significant problems we face cannot be solved by the same level of thinking that created them." - Albert Einstein

  2. #22
    Join Date
    Sep 2004
    Posts
    1,905
    Rep Power
    21

    Default

    I was wrong about all that I said before. Much of it I do not know

    I was also trying to figure out all the nicks and crannys about using the ids, veiwstates, the effects of where the code was done in the page cylce, the various methods for adding dynamic controls and I would have to be a experienced guru to answer them all. This was my experiment bed.
    Code:
    override protected void OnInit(EventArgs e)
    {
    	//Should find Placeholder instead
        Control form = Page.FindControl("Form1");
        form.EnableViewState    =    false;
    
        //Add stuff
        TextBox txtBox1 = new TextBox();
        txtBox1.EnableViewState = false;
        //txtBox1.ID    =    "id1";
        form.Controls.Add(txtBox1);
    
        //Add stuff
        Literal lit1 = new Literal();
        lit1.Text = "<br><hr><br><hr><br>";
        form.Controls.Add(lit1);
    
        //Add stuff
        TextBox txtBox2 = new TextBox();
        txtBox2.EnableViewState = false;
        //txtBox2.ID    =    "id2";
        form.Controls.Add(txtBox2);
    
        /*
        //Test re-adding a pre added control
        lit1.Text = "<br><br>";
        form.Controls.Add(lit1);
        */
    
        //Add stuff
        Literal lit2 = new Literal();
        lit2.Text = "<br><br><br>";
        form.Controls.Add(lit2);
    
        //Add stuff
        Control txtBox3 = new WebControl(HtmlTextWriterTag.Input);
        txtBox3.ID = "id3";
        txtBox3.EnableViewState = false;
        form.Controls.Add(txtBox3);
    
        //Add stuff
        Literal lit3 = new Literal();
        lit3.Text = "<br><INPUT type=\"submit\" value=\"Submit\"><br>";
        form.Controls.Add(lit3);
    
        //Add stuff
        Literal lit4 = new Literal();
        lit4.ID = "id4";
        lit4.EnableViewState = false;
        lit4.Text = "<br><input type=\"text\" /><br>";
        form.Controls.Add(lit4);
    
        //Add stuff
        HtmlInputText txtBox5 = new HtmlInputText();
        txtBox5.ID = "id5";
        txtBox5.EnableViewState = false;
        txtBox5.Value = "end";
        form.Controls.Add(txtBox5);
    
        /*
        //Add stuff
        TextBox    txtBox6 =    new TextBox();
        txtBox6.ID    =    "id6";
        txtBox6.EnableViewState    =    false;
        txtBox6.Text    =    "end2";
        form.Controls.Add(txtBox6);
        */
    
        //
        // CODEGEN: This call is required by the ASP.NET Web Form Designer.
        //
        InitializeComponent();
        base.OnInit(e);
    }
    Getting dynamic controls is easy however, just watch out for other little bugs in your code that can mislead you like forgetting to take out test statements
    Let's act on what we agree on now, and argue later on what we don't.
    Black men leave Barbeque alone if Barbeque don't trouble you

  3. #23
    Join Date
    Sep 2004
    Posts
    1,905
    Rep Power
    21

    Default

    Just juggle some more code using the post back. This time I was using ASP.Net 2.0

    I added this code to the Init method
    Code:
    //Add varying stuff
    if (Page.Session.Count == 0)
    {
        Page.Session.Add("num", 1);
    }
    else
    {
        int n = (int)Page.Session["num"];
    
        for (int i = 0; i < n; i++)
        {
            //Add stuff
            TextBox txtBox = new TextBox();
            txtBox.Text = "text" + i.ToString();
            form.Controls.Add(txtBox);
        }
    
        Page.Session["num"] = n + 1;
    }
    View state was saved automatically without prgramatically accessing the StateBag of the page. I did not test the effects of the PostBack property here. Would like to see any examples where the view state is set programatically.

    I tested another code in the Load method after removing the Init method. The Page Load was always called twice. I never realized how much that affects the code until used with dynamic controls. Anyways, the view state was saved automatically. On thing though, controls that are added in the second load call, do not save state. But once the controls are added, they will save state. I also noticed that the nth control always had the same state even when controls are inserted before it and take its state position. This I may have noticed wrong. This was what I was playing with
    Code:
    protected void Page_Load(object sender, EventArgs e)
    {
        Control form = Page.FindControl("Form1");//Should find Placeholder
        //form.EnableViewState	=	false;
    
        //Add stuff
        Literal lit00 = new Literal();
        lit00.Text = "<br><INPUT type=\"submit\" value=\"Submit\"><br>";
        form.Controls.Add(lit00);
    
        if (Page.IsPostBack)//(true)//(!Page.IsPostBack)
        {
            //Add stuff
            Literal lit = new Literal();
            lit.Text = "<br><INPUT type=\"submit\" value=\"Submit\"><br>";
            form.Controls.Add(lit);
    
            if (Page.Session.Count == 0)
            {
                Page.Session.Add("num", 0);
            }
            else
            {
                int n = (int)Page.Session["num"];
                Page.Session["num"] = n + 1;
                for (int i = 0; i < n; i++)
                {
                    //Add stuff
                    TextBox txtBox = new TextBox();
                    //txtBox.EnableViewState = false;
                    txtBox.Text = sender.ToString() + i.ToString();
                    //txtBox.EnableViewState = false;
                    form.Controls.Add(txtBox);
                }
            }
        }
        else
        {
        }
    }
    View state was saved automatically. I edited various text boxes and clicked submit, change up the code a bit and test again. Sometimes the view state was not saved for freshly added controls in the second call of Load. Perhaps this could have been done programmatically eg ViewState["id"] = "data".

    There was a double call on the Load method and I did not consider using the else method of this if to fix the problem
    Code:
    if (Page.IsPostBack)//(true)//(!Page.IsPostBack)
    I could also implement another if to use just the first Load call. I am not sure if the page was bug free or if something else called the Load method explicitly.



    @icymint,
    I agree with A-->D all that you said. It works. I am a novice to dynamic controls. There is much different implementations that I have not tested. Sometimes you can use the IsPost back and sometimes you do not, but again I am just a novice, so I could be wrong.

    To get dynamic controls working, you have to debug a little, but any unforseen bug can throw you off track and that is what happened to us.
    Let's act on what we agree on now, and argue later on what we don't.
    Black men leave Barbeque alone if Barbeque don't trouble you

  4. #24
    Join Date
    Sep 2004
    Posts
    1,905
    Rep Power
    21

    Default

    Corrections with the two call on the Load method. There is just one call on the Load method.

    I do not know what caused that to happen before. I realized that I was using a very old beta version of ASP.Net

    Just now, I installed VWD ASP.Net 2.0. The Page Load is call just once. Well that fixes the problem with the double post. The view state is now saved all the time for the previous tests.

    I will try using a PlaceHolder and just write the dynamic controls with them. I will also try manually setting the view state for any controls that were created in the PlaceHolder by writting the controls with just literal values.
    Let's act on what we agree on now, and argue later on what we don't.
    Black men leave Barbeque alone if Barbeque don't trouble you

  5. #25
    Join Date
    Jul 2004
    Posts
    153
    Rep Power
    0

    Default checking for postback is not enough

    Quote Originally Posted by icymint3
    there is no need to do what you guys are doing.
    that is bad programming and you know it.

    all that said.

    A. if you want dynamic controls only add them after checking IsPostback property
    B. do not add them again if the form IsPosted back.
    C. set unique ids for the controls you use.
    D. design before code ( at least draw what you want to see on paper, link them with arrows for page loads and postbacks).
    ..
    At first glance this might seem to work...but it proved otherwise atleast in my implementation...which for some reason went wrong.

    (A,B) checking for postback (in page_load()) alone did not work its making sure its in the right place...for at this time the page already went through 80-90% of the page cycle without the controls.
    init->load->{dispaly_controls()}...so on the first load of the page..the cycle has no 'knowledge' of the controls...if i left [dispaly_controls()] out of the equation on postback..the controls would dissappear...and trust me they did..this is where page_init() comes in....

    (C) each control had unique ids..it would be pointless otherwise.
    (D) Good advice - but that was done...its good practice...

    respect still....

  6. #26
    Join Date
    Dec 2002
    Posts
    500
    Rep Power
    0

    Default

    the code you wrote would output html with incorrectly ordered tags

    Code:
    <span ...> <table ...> </span> 
    <span> <tr ...><td> dfgdsfg </td></tr></span>
    <span> <tr ...><td> dfgdsfg </td></tr></span>
    <span> <tr ...><td> dfgdsfg </td></tr></span>
    <span> </table> </span>
    thats what im talking about when i said bad programming.

    if you wanted dynamic controls i would suggest making a user control or a web control. now instead of being created dynamically, you only add them to the form dynamically... ill explain more when i reach home.
    Last edited by icymint3; May 2, 2006 at 06:28 PM.
    Cultured in Aggression and Koding like a Warrior!!
    “Common sense is instinct. Enough of it is genius.” - George Bernard Shaw.
    "The significant problems we face cannot be solved by the same level of thinking that created them." - Albert Einstein

  7. #27
    Join Date
    Sep 2004
    Posts
    1,905
    Rep Power
    21

    Default

    About the Page_Load being called twice - cause AutoEventWireUp
    I noticed that the Page onload was called twice in one of my implementations. This was because AutoEventWireup was set to true.

    In VS2002, AutoEventWireUp is default to false and event handlers must be registered with event += handler
    If AutoEventWireUp is true then you can use Page_Load without registering it.
    In VS2005, AutoEventWireUp was set to true somehow, so that cause the Page_Load handler to trigger twice. (When I was porting the code, I did only copy certain sections and ignored AutoEventWireUp)


    About ids
    I agree with you both that the ids should be unique if even for good practice. Some framework code will throw exceptions for un-unique ids.

    I tested out the purpose of the ids with respect to the View State.
    This code displays 5 text boxes at the bottom with ids being "id1" to "id5". Some of these 5 text boxes can be removed by typing in theirs ids into the topmost text box eg "id1 id3" then clicking the send button twice, oops. Type some text into the 5 text boxes and then remove one of them. Note how the id has purpose in this case.

    Code:
    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 DynTest7
    {
    	/// <summary>
    	/// Summary description for WebForm1.
    	/// </summary>
    	public class WebForm1 : System.Web.UI.Page
    	{
    		private void Page_Load(object sender, System.EventArgs e)
    		{
    			// Load the session state with the id list from the top control
    			TextBox txtBoxMain =	(TextBox) Page.FindControl("main_edit");
    			string[] strIds = txtBoxMain.Text.Split(' ', '\t', ',');
    
    			if(Page.Session["idList"] != null)
    			{
    				ArrayList	listIds	=	(ArrayList)Page.Session["idList"];
    				listIds.Clear();
    				listIds.AddRange(strIds);
    				listIds.Sort();
    			}
    		}
    
    		#region Web Form Designer generated code
    		override protected void OnInit(EventArgs e)
    		{
    			Control form = Page.FindControl("Form1");//Should find Placeholder
    
    			#region		Main Controls
                //Add main edit control
    			TextBox txtBoxMain = new TextBox();
    			txtBoxMain.ID	=	"main_edit";
    			txtBoxMain.Width	=	Unit.Pixel(150);
    			form.Controls.Add(txtBoxMain);
    
    			//Fillings
    			Literal litFillMain1 = new Literal();
    			litFillMain1.ID = "main_fill1";
    			litFillMain1.Text = "<br>";
    			form.Controls.Add(litFillMain1);
    
    			//Add main buttton control
    			Button	butSendMain	=	new Button();
    			butSendMain.ID	=	"main_button";
    			butSendMain.Width	=	Unit.Pixel(150);
    			butSendMain.Text	=	"Send\n(type the id(s) to remove)";
    			form.Controls.Add(butSendMain);
    
    			//Fillings
    			Literal litFillMain2 = new Literal();
    			litFillMain2.ID = "main_fill2";
    			litFillMain2.Text = "<br><br>";
    			form.Controls.Add(litFillMain2);
    			#endregion
    
    
    			if(Page.Session["idList"] == null)
    			{
    				Page.Session.Add("idList", new ArrayList());
    			}
    
    			ArrayList	listIds;
    			listIds	=	(ArrayList)Page.Session["idList"];
    
    			if(listIds != null)
    			{
    				for(int i = 1; i <= 5; i++)
    				{
    					string strId	=	"id" + i.ToString();
    					if(listIds.BinarySearch(strId) < 0)
    					{
    						//Add stuff only if the id is not in the list
    						TextBox txtBox = new TextBox();
    						txtBox.ID	=	strId;
    						form.Controls.Add(txtBox);
    					}
    				}
    			}
    
    			//
    			// 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);
    
    		}
    		#endregion
    	}
    }

    About notes made while debugging with VS2005
    This is from recall.

    There is a state bage (ViewState) for each control. It holds two hashes, "type" and "value". The value of "type" is usually "text" and the value of "value" is "the view text that is saved" e.g. a textbox server control. Put mytextbox.ViewState , mytextbox.ViewState["type"], mytextbox.ViewState["value"] in the watch window. This shows up in VS2005. I have not gotten it to work with VS2002 even after trying mytextbox.ViewState["value"] and mytextbox.ViewState["Value"] when mytextbox.ViewState.Count equals 2.

    The ViewState property of the derived page is not the state bag that contains all the states of all controls on the page. Some other state bage does this behind the scenes. It seems to update or be connected with all the other state bags.

    The ViewState property has protected access. Inside the derived web page, or derived control, ViewState is accessible.

    I will try to debug more when I am using VS2005


    About deriving a new control

    That would be nice I could try a simply one for next time.
    Let's act on what we agree on now, and argue later on what we don't.
    Black men leave Barbeque alone if Barbeque don't trouble you

  8. #28
    Join Date
    Jul 2004
    Posts
    153
    Rep Power
    0

    Default bad coding...indeed

    Quote Originally Posted by icymint3
    the code you wrote would output html with incorrectly ordered tags

    Code:
    <span ...> <table ...> </span> 
    <span> <tr ...><td> dfgdsfg </td></tr></span>
    <span> <tr ...><td> dfgdsfg </td></tr></span>
    <span> <tr ...><td> dfgdsfg </td></tr></span>
    <span> </table> </span>
    thats what im talking about when i said bad programming.

    if you wanted dynamic controls i would suggest making a user control or a web control. now instead of being created dynamically, you only add them to the form dynamically... ill explain more when i reach home.
    OK...u'r right about that...can't argue that one...that has since changed...and now use literals instead..it was an oversight..considering that at the time it worked(to display the controls in the desired structure).

    No need to explain...i'm quite aware of you are talking about.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •