Results 1 to 4 of 4

Thread: Dynamic Control Loading

  1. #1

    Thread Starter
    Frenzied Member
    Join Date
    Aug 2000
    Location
    Birmingham, AL
    Posts
    1,276

    Question Dynamic Control Loading

    I have a problem that I can't solve when I load controls dynamically. I have 3 states on a page that I traverse through and I load as many buttons on the page as the page state number + 1. For example, on state 0, I load 1 button, state 2 - 2 buttons, etc.

    The problem is after I move to a new page state, the button click event(s) of the dynamic buttons will not be wired up and won't fire until the second click of each button.

    CSharp Code:
    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Web;
    5. using System.Web.UI;
    6. using System.Web.UI.WebControls;
    7.  
    8. namespace WebTest
    9. {
    10.     public partial class DynamicButtonTest : System.Web.UI.Page
    11.     {
    12.         private int _PageState {
    13.             get {
    14.                 if(ViewState["PageState"] != null) {
    15.                     return (int)ViewState["PageState"];
    16.                 }
    17.                 return 0; // default
    18.             }
    19.             set {
    20.                 ViewState["PageState"] = value;
    21.             }
    22.         }
    23.  
    24.         private void LoadButtons(int pageState) {
    25.  
    26.             panelButtons.Controls.Clear();
    27.  
    28.             for(int i = 0; i < pageState + 1; i++) {
    29.                 Button b = new Button();
    30.                 b.Text = i.ToString();
    31.                 b.Click += new EventHandler(b_Click);
    32.  
    33.                 panelButtons.Controls.Add(b);
    34.             }
    35.  
    36.             _PageState = pageState;
    37.         }
    38.  
    39.         void b_Click(object sender, EventArgs e) {
    40.             Button b = (Button)sender;
    41.             Response.Write("Button " + b.Text + " was clicked.");
    42.         }
    43.  
    44.         protected void Page_Load(object sender, EventArgs e) {
    45.  
    46.             if(!IsPostBack) {
    47.                 LoadButtons(0);
    48.             }
    49.             else {
    50.                 LoadButtons(_PageState);
    51.             }
    52.         }
    53.  
    54.         protected void btnBack_Click(object sender, EventArgs e) {
    55.  
    56.             switch(_PageState) {
    57.                 case 0:
    58.                     // Initial State - do nothing
    59.                     break;
    60.                 case 1:
    61.                     // move to PageState 0
    62.                     LoadButtons(0);
    63.                     break;
    64.                 case 2:
    65.                     // move to PageState 1
    66.                     LoadButtons(1);
    67.                     break;
    68.                 default:
    69.                     break;
    70.             }
    71.         }
    72.  
    73.         protected void btnNext_Click(object sender, EventArgs e) {
    74.  
    75.             switch(_PageState) {
    76.                 case 0:
    77.                     // move to PageState 2
    78.                     LoadButtons(1);
    79.                     break;
    80.                 case 1:
    81.                 // move to PageState 3
    82.                     LoadButtons(2);
    83.                     break;
    84.                 case 2:
    85.                     // Last State - do nothing
    86.                     break;
    87.                 default:
    88.                     break;
    89.             }
    90.         }
    91.     }
    92. }


    PHP Code:
    <&#37;@ Page Language="C#" AutoEventWireup="true" CodeBehind="DynamicButtonTest.aspx.cs" Inherits="WebTest.DynamicButtonTest" %>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <
    html xmlns="http://www.w3.org/1999/xhtml" >
    <
    head runat="server">
        <
    title></title>
    </
    head>
    <
    body>
        <
    form id="form1" runat="server">
        <
    div>
            <
    asp:Button ID="btnBack" runat="server" Text="Back" onclick="btnBack_Click" /><asp:Button ID="btnNext" runat="server" Text="Next" onclick="btnNext_Click" />
            <
    asp:Panel ID="panelButtons" runat="server">
            </
    asp:Panel>
        </
    div>
        </
    form>
    </
    body>
    </
    html
    Last edited by wey97; Mar 12th, 2010 at 01:36 PM. Reason: Changed Session to ViewState to make the state reset when a new page is opened.

  2. #2

    Thread Starter
    Frenzied Member
    Join Date
    Aug 2000
    Location
    Birmingham, AL
    Posts
    1,276

    Re: Dynamic Control Loading

    Page_Load could be simplifed to
    CSharp Code:
    1. protected void Page_Load(object sender, EventArgs e) {
    2.     LoadButtons(_PageState);
    3. }
    Last edited by wey97; Mar 12th, 2010 at 04:16 PM.

  3. #3

    Thread Starter
    Frenzied Member
    Join Date
    Aug 2000
    Location
    Birmingham, AL
    Posts
    1,276

    Re: Dynamic Control Loading

    I found a way to make this work but it's far from ideal. Before I add a control to the panelButtons control collection, I check to see if a control with the same text already exists.

    CSharp Code:
    1. private void LoadButtons(int pageState) {
    2.  
    3.     for(int i = 0; i < pageState + 1; i++) {
    4.         Button b = new Button();
    5.         b.Text = i.ToString();
    6.         b.Click += new EventHandler(b_Click);
    7.  
    8.         bool found = false;
    9.  
    10.         foreach(Control ctrl in panelButtons.Controls) {
    11.  
    12.             if(ctrl.GetType() == typeof(Button)) {
    13.                 Button btn = (Button)ctrl;
    14.  
    15.                 if(btn.Text == b.Text) {
    16.                     found = true;
    17.                     break;
    18.                 }
    19.             }
    20.         }
    21.  
    22.         if(!found) {
    23.             panelButtons.Controls.Add(b);
    24.         }
    25.  
    26.     }
    27.  
    28.     _PageState = pageState;
    29. }

    How can this be avoided?

    EDIT:

    Simplified way to not insert duplicate control.

    CSharp Code:
    1. private void LoadButtons(int pageState) {
    2.  
    3.     for(int i = 0; i < pageState + 1; i++) {
    4.         Button b = new Button();
    5.  
    6.         b.ID = this.ID + "_button_" + i.ToString();
    7.         b.Text = i.ToString();
    8.         b.Click += new EventHandler(b_Click);
    9.  
    10.  
    11.         if(panelButtons.FindControl(b.ID) == null) {
    12.             panelButtons.Controls.Add(b);
    13.         }
    14.     }
    15.     _PageState = pageState;
    16. }

    It still seems like there should be a more straightforward way to do this.
    Last edited by wey97; Mar 12th, 2010 at 01:53 PM.

  4. #4
    PowerPoster gep13's Avatar
    Join Date
    Nov 2004
    Location
    The Granite City
    Posts
    21,963

    Re: Dynamic Control Loading

    Hey,

    This is not a direct answer to your question by any means, but I would strongly recommend that you have a look at this article:

    http://www.4guysfromrolla.com/articles/092904-1.aspx

    Gary

Posting Permissions

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



Click Here to Expand Forum to Full Width