CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 3 of 3
  1. #1
    Join Date
    Nov 2008
    Posts
    1

    Remove element from ArrayList through autogenerated Button

    Hello,
    I need to code a project for school in c#, everything was going smoothly, till i tried to do the following:
    I have an ArrayList of objects, I want to generate Buttons which, when i click it, deletes the corresponding item in the ArrayList, sounds pretty straight forward, right?
    So I started coding, it didn't really went as smoothly as planned, so I started coding it seperately in a testproject, where it still didn't work... For some reason, the following code works, but only if i click the button twice, which obviously isn't the plan.

    WebForm1.cs
    Code:
    using System;
    using System.Collections;
    using System.Configuration;
    using System.Data;
    using System.Linq;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.HtmlControls;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    
    namespace programmerenproject
    {
        public partial class WebForm1 : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                ArrayList list;
    
                if (!IsPostBack)
                {
                    list = new ArrayList();
                    list.Add("test1");
                    list.Add("test2");
                    list.Add("test3");
                    list.Add("test4");
                    ViewState["list"] = list;
                    generateButtons(list);
                }
                else
                {
                    list = (ArrayList)ViewState["list"];
                    generateButtons(list);
                }
            }
    
            private void ClickMe(object sender, System.EventArgs e)
            {
                ArrayList list = (ArrayList)ViewState["list"];
    
                MyButton who = (MyButton)sender;
                list.RemoveAt(who.Element);
                lblTest.Text = list[who.Element].ToString();
                generateButtons(list);
    
                ViewState["list"] = list;
            }
    
            public void generateButtons(ArrayList l)
            {
                pnlTest.Controls.Clear();
                int number = l.Count;
                MyButton[] myButtons = new MyButton[number];
                for (int i = 0; i < number; i++)
                {
                    myButtons[i] = new MyButton(i);
                    myButtons[i].Text = l[i].ToString();
                    myButtons[i].Click += new System.EventHandler(this.ClickMe);
                    pnlTest.Controls.Add(myButtons[i]);
                }
            }
        }
    
    
    }
    MyButton.cs (extends Button so I can add some extra data behind the button)
    Code:
    using System;
    using System.Data;
    using System.Configuration;
    using System.Linq;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.HtmlControls;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Xml.Linq;
    using System.Collections;
    
    namespace programmerenproject
    {
        public class MyButton:Button
        {
            int element;
    
            public int Element
            {
                get { return element; }
                set { element = value; }
            }
    
            public MyButton(int e)
            {
                element = e;
            }
    
        }
    }
    WebForm1.aspx
    Code:
    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="programmerenproject.WebForm1" %>
    
    <!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>Untitled Page</title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>  
        
            <asp:Panel ID="pnlTest" runat="server">
            </asp:Panel>
            <asp:Label ID="lblTest" runat="server"></asp:Label>
        
            <br />
        
        </div>
        </form>
    </body>
    </html>
    I hope someone can point out my problem... or give me a pointer in the right direction

  2. #2
    Join Date
    Mar 2005
    Location
    Vienna, Austria
    Posts
    4,538

    Re: Remove element from ArrayList through autogenerated Button

    There are different problems !
    One I have solved for you is that it doesn't show you the correct item you have deleted
    Code:
    public partial class _Default : System.Web.UI.Page 
    {
        private ArrayList list;    
        protected void Page_Load(object sender, EventArgs e)
            {
                
                if (!IsPostBack)
                {
                    list = new ArrayList();
                    list.Add("test1");
                    list.Add("test2");
                    list.Add("test3");
                    list.Add("test4");
                    ViewState["list"] = list;
                    generateButtons(list);
                }
                else
                {
                   list = (ArrayList)ViewState["list"];
                   generateButtons(list);
                }
            }
            private void ClickMe(object sender, System.EventArgs e)
            {
                MyButton who = (MyButton)sender;
                // now we show which button is removed 
                lblTest.Text = list[who.Element].ToString();
                // we remove the button whoms text is shown
                list.RemoveAt(who.Element);
                // now we have one button less so the listindex are changed
                generateButtons(list);
                ViewState["list"] = list;
            }
            public void generateButtons(ArrayList l)
            {
                pnlTest.Controls.Clear();
                int number = l.Count;
                MyButton[] myButtons = new MyButton[number];
                for (int i = 0; i < number; i++)
                {
                    myButtons[i] = new MyButton(i);
                    myButtons[i].Text = l[i].ToString();
                    myButtons[i].Click += new System.EventHandler(this.ClickMe);
                    pnlTest.Controls.Add(myButtons[i]);
                }
            }
        }
    As you see I'm using a private field for your Arraylist so I didn't need to load it from the viewstate when the click event is called.
    The othe problem simple has to do with the fact that the index changes when you remove an item in a list. So you need to show its name in the label before you remove it !! Or you will get a wrong item when doing after deletion Use the debugger and you will see this.

    The problem with not getting every click i havn't solved in between.
    But why nor simple using an repeater for adding/removing buttons dynamically

    ----- edited ------
    look at my next post for a full solution of your problems.
    Last edited by JonnyPoet; November 30th, 2008 at 03:30 PM.
    Jonny Poet

    To be Alive is depending on the willingsness to help others and also to permit others to help you. So lets be alive. !
    Using Code Tags makes the difference: Code is easier to read, so its easier to help. Do it like this: [CODE] Put Your Code here [/code]
    If anyone felt he has got help, show it in rating the post.
    Also dont forget to set a post which is fully answered to 'resolved'. For more details look to FAQ's about Forum Usage. BTW I'm using Framework 3.5 and you ?
    My latest articles :
    Creating a Dockable Panel-Controlmanager Using C#, Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 | Part 7

  3. #3
    Join Date
    Mar 2005
    Location
    Vienna, Austria
    Posts
    4,538

    Re: Remove element from ArrayList through autogenerated Button

    Hi !
    I have done a bit more research and here is the working code
    Code:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Collections;
    public partial class _Default : System.Web.UI.Page {
        private List<Button> list;
        private ArrayList txtList;
        protected void Page_Load(object sender, EventArgs e) {
            if (!IsPostBack) {
                txtList = new ArrayList();
                txtList.Add("Wert1");
                txtList.Add("Wert2");
                txtList.Add("Wert3");
                txtList.Add("Wert4");
                txtList.Add("Wert5");
                txtList.Add("Wert6");
                generateButtons(txtList);
                Session.Add("list", txtList);
            }
        }
        private void ClickMe(object sender, System.EventArgs e) {
            Button who = (Button)sender;
            // now we show which button is removed 
            lblTest.Text = who.Text.ToString();
            // we remove the button whoms text is shown
            txtList.Remove(lblTest.Text);
            // now we have one button less so the listindex are changed
            generateButtons(txtList);
            Session["list"] = txtList;
        }
        public void generateButtons(ArrayList lt) {
            list = new List<Button>();
            pnlTest.Controls.Clear();
            pnlTest.EnableViewState = true;
            int number = lt.Count;
            for (int i = 0; i < number; i++) {
                Button myButton = new Button();
                // we need to make them different ID's so they work without any problems
                myButton.ID = "DynButton" + (i + 1).ToString();
                myButton.Text = lt[i].ToString();
                //myButton.EnableViewState = true; 
                myButton.Click += new System.EventHandler(this.ClickMe);
                list.Add(myButton);
                pnlTest.Controls.Add(myButton);
            }
        }
         /// <summary>
         /// We generate dynamic controls here ! See MSDN reference attached
         /// </summary>
         /// <param name="e"></param>
        protected override void OnPreInit(EventArgs e) {
            if (IsPostBack) {
                txtList = (ArrayList)Session["list"];
                generateButtons(txtList);
            }
            base.OnPreInit(e);
        }
    }
    // And the aspx Page is like this:
    <%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>
    
    <!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:Panel ID="pnlTest" runat="server" EnableViewState="true"  >
            </asp:Panel>
            <asp:Label ID="lblTest" runat="server"></asp:Label>
        
            <br />
        
        </div>
        </form>
    
    </body>
    </html>
    I havn't used any namespace and also I was using standard buttons.
    But it will work with your buttons in the same way

    And here is a reference why we do it this way.
    http://msdn.microsoft.com/en-us/library/ms178472.aspx

    Especially look on when to generate the controls after a postback. Its done in OnPreInit as you can see at MSDN. Setting different ID's lets your Controls delegates work. It will not work properly without them. Try it, debug it and you will see it works Every hit to a button also generates an event that could be catched by the correct event handler.
    Last edited by JonnyPoet; November 30th, 2008 at 03:29 PM.
    Jonny Poet

    To be Alive is depending on the willingsness to help others and also to permit others to help you. So lets be alive. !
    Using Code Tags makes the difference: Code is easier to read, so its easier to help. Do it like this: [CODE] Put Your Code here [/code]
    If anyone felt he has got help, show it in rating the post.
    Also dont forget to set a post which is fully answered to 'resolved'. For more details look to FAQ's about Forum Usage. BTW I'm using Framework 3.5 and you ?
    My latest articles :
    Creating a Dockable Panel-Controlmanager Using C#, Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 | Part 7

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

Featured