How to Locate and Delete a PictureBox that was created with an Array

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Dalamar437
    New Member
    • Mar 2010
    • 6

    How to Locate and Delete a PictureBox that was created with an Array

    Hello All,
    I am in desperate need of your smarts!

    I'm attempting to auto generate X number of pictureboxes when a program loads.
    I'm generating 2 different arrays that will produce some number of picture boxes.
    When I click button 1, I want to send a separate picture box near one of the auto generated picture boxes and remove a designated-array-generated picture box. I do not want to remove all picture boxes, only a set amount.

    For more clarification.. ..
    I'm not looking for the program to do this: "if picturebox1 is close to pictureboxArray 1[] then delete some number of picture boxes in that array"

    I'm looking to do this: "if picturebox1 is sent to area A then delete some number of picture boxes in the array that belongs to area A"

    If you're looling at the attached .jpg, the blue picture box will move close to the red or green picture boxes (randomly) and I'm lost on how to get it to delete the picture box once it arrives in one of those destinations. I can delete the pictureboxes just fine on a double click but that's all i've pulled off!
    Code is attached in PictureBoxArray AndDelete.txt

    Thanks again!
    Attached Files
  • tlhintoq
    Recognized Expert Specialist
    • Mar 2008
    • 3532

    #2
    Just remove the picturebox from the picturebox[]

    Change 1: Instead of an array of pictureboxes change to a List<> since it is friendlier

    Code:
    private List<PictureBox> ManyPictureBoxesTop;
    private List<PictureBox> ManyPictureBoxesBottom;
    Now you can easily remove items from the middle of the list

    Code:
    ManyPictureBoxesTop.RemoveAt(14);
    You could continue to do it with an array, but to remove something from the middle of an array you have to loop through it and move everything down one index... Item 9 becomes item 10, 10 becomes 11, 11 becomes 12... 30 becomes null, array needs to be resized to the new smaller number.... It's a pain.

    A List<> has methods for Add, AddRange, Remove, RemoveAt etc. I think you'll find it a more friendly type.
    Represents a strongly typed list of objects that can be accessed by index. Provides methods to search, sort, and manipulate lists.

    Comment

    • Dalamar437
      New Member
      • Mar 2010
      • 6

      #3
      I'm still doing something wrong...

      You give me far too much credit in trying to work that out :)
      It keeps thinking that private List<PictureBox > listPictureBoxe s1; is null?



      Code:
       private void generatelistPictureboxes1(int numofPBs, int xstart, int ystart)
        {
           int horizontalspacing = 5;
           int verticalspacing = 3;
             for (int i = 0; i < numofPBs; i++)
                  {
                    horizontalspacing = horizontalspacing + 5; //stagger the picture boxes
                      verticalspacing = verticalspacing + 3; //stagger the picture boxes
                      List<PictureBox> listPictureBoxes1 = new List<PictureBox>();
                      PictureBox pic = new PictureBox();
                      listPictureBoxes1.Add(pic);  //add a picture box to the list
                 splitContainer2.Panel1.Controls.Add(pic); // add a picturebox to the form
                      pic.Size = new System.Drawing.Size(20, 10);
         pic.Location = new System.Drawing.Point(xstart + horizontalspacing, ystart + verticalspacing);
                      pic.BackColor = Color.Purple;
                      pic.BorderStyle = BorderStyle.FixedSingle; 
                      pic.BringToFront();
                  }
              }
      is this not the right way to add each picture box to the list?
      listPictureBoxe s1.Add(pic);

      Comment

      • tlhintoq
        Recognized Expert Specialist
        • Mar 2008
        • 3532

        #4
        Without opening Visual Studio and trying it in a project, it looks right

        Wait... You are declaring that listPictureBoxe s is a new list INSIDE your loop, thus resetting every time you loop through.

        You need to create that list OUTSIDE of ANY method so you can have access to it throughout your application.

        Code:
        List<PictureBox> listPictureBoxes1 = new List<PictureBox>();
        
         private void generatelistPictureboxes1(int numofPBs, int xstart, int ystart)
          {
             int horizontalspacing = 5;
             int verticalspacing = 3;
               for (int i = 0; i < numofPBs; i++)
                    {
                      horizontalspacing = horizontalspacing + 5; //stagger the picture boxes
                        verticalspacing = verticalspacing + 3; //stagger the picture boxes
                        PictureBox pic = new PictureBox();
                        listPictureBoxes1.Add(pic);  //add a picture box to the list
                   splitContainer2.Panel1.Controls.Add(pic); // add a picturebox to the form
                        pic.Size = new System.Drawing.Size(20, 10);
           pic.Location = new System.Drawing.Point(xstart + horizontalspacing, ystart + verticalspacing);
                        pic.BackColor = Color.Purple;
                        pic.BorderStyle = BorderStyle.FixedSingle; 
                        pic.BringToFront();
                    }
                }
        Now that the list has a scope of your entire class, any method within the class will see it.

        Comment

        • tlhintoq
          Recognized Expert Specialist
          • Mar 2008
          • 3532

          #5
          You give me far too much credit in trying to work that out :)
          Obviously not - you did it just right with only one tiny hiccup. Very well done!

          Comment

          • Dalamar437
            New Member
            • Mar 2010
            • 6

            #6
            woohoo! I got it!

            You were right to take the
            List<PictureBox > listPictureBoxe s1 = new List<PictureBox >();
            out of the for loop, but the deleting part was a nightmare! I was getting tons of errors that I was trying to remove controls that were out of range.

            Here is how I got the delete to work:
            Code:
            private int moveBlueBox(int minimumIncrease)
             {
               int randomDestination = RandomNumber(1 + minimumIncrease, 100);
               int firstindex = 0;
               int lastindex1;
               int lastindex2;
            
                if (randomDestination >= 50)
                   {
                    //redraw the blue picture box into the proper split container
                     splitContainer2.Panel1.Controls.Add(pictureBox1);  
                      this.pictureBox1.Location = new System.Drawing.Point(70, 40);
                     
                     lastindex1 = listPictureBoxes1.Count; //count the indexes in the list
                     lastindex1 = lastindex1 - 1;
                     
                     if (listPictureBoxes1 != null && lastindex1 >= 0)
                        {
                          listPictureBoxes1.RemoveAt(firstindex);
                          //delete the picture box control in the split container
                          splitContainer2.Panel1.Controls.RemoveAt(firstindex);
                          
                          label1.Text = "removed picturebox at index " + lastindex1;
                         
                           if (lastindex1 == 0)
                             {
                              listPictureBoxes1.Clear(); //clear the list
                              }
                          }
                          else
                          {
                            label1.Text = "no more to delete!";
                           }
                        }
            
                if (randomDestination <= 49)
                   {
                     //redraw the blue picture box into the proper split container
                     splitContainer2.Panel2.Controls.Add(pictureBox1);
                     this.pictureBox1.Location = new System.Drawing.Point(70, 40);
                                       
                      lastindex2 = listPictureBoxes2.Count; //count the indexes in the list
                      lastindex2 = lastindex2 - 1;
            
                       if (listPictureBoxes2 != null && lastindex2 >= 0)
                         {
                           listPictureBoxes2.RemoveAt(firstindex);
                          //delete the picture box control in the split container
                           splitContainer2.Panel2.Controls.RemoveAt(firstindex); 
                          
                           label2.Text = "removed picturebox at index " + lastindex2;
                           
                            if (lastindex2 == 0)
                               {
                                 listPictureBoxes2.Clear();
                               }
                            }
                            else
                            {
                              label2.Text = "no more to delete!";
                            }
                        }
                        return 0;
                    }
            Thanks so much for all your help!
            I've attached the entire working code.
            Attached Files

            Comment

            • tlhintoq
              Recognized Expert Specialist
              • Mar 2008
              • 3532

              #7
              Allow me to give you something to dissassemble and study.

              Clicking the 'move' button does nothing more than flip a coin and move the blue box. How the panel reacts to the blue box is handled in it's own event handler. The button isn't made god of the board.

              A couple methods that were nearly identical were made into a single method, that takes a couple parameters so make it more re-usable.

              The 'Generation' of boxes has been split from the 'placement' of boxes. They are different functions and shouldn't be muddy'ed up with responsibilitie s beyond their purpose.

              Code:
              namespace WindowsFormsApplication1
              {
                  using System;
                  using System.Collections.Generic;
                  using System.ComponentModel;
                  using System.Data;
                  using System.Drawing;
                  using System.Text;
                  using System.Windows.Forms;
              
                  public partial class Form1 : Form
                  {
                      #region Fields
                      List<PictureBox> TopBoxes = new List<PictureBox>();
                      List<PictureBox> BottomBoxes = new List<PictureBox>();
              
                      int horizontalspacing = 5;
                      int verticalspacing = 3;
                      #endregion Fields
              
                      #region Constructors
                      public Form1()
                      {
                          InitializeComponent();
              
                          SetupGameboard();
                      }
                      #endregion Constructors
              
                      #region Methods
              
                      private void btnReset_Click(object sender, EventArgs e)
                      {
                          SetupGameboard();
                      }
              
                      private void button1_Click(object sender, EventArgs e)
                      {
                          FlipCoin();
                      }
              
                      private void FlipCoin()
                      {
                          int randomDestination = RandomNumber(1, 100);
              
                          if (randomDestination >= 50)
                          {
                              splitContainer2.Panel1.Controls.Add(pictureBox1);
                          }
                          else
                          {
                              splitContainer2.Panel2.Controls.Add(pictureBox1);
                          }
                      }
              
                      void GenerateBoxes(List<PictureBox> WhichList, int MaxBoxes, Color BoxColor)
                      {
                          int RandomMax = RandomNumber(1, MaxBoxes);
                          for (int Index = 0; Index < RandomMax; Index++)
                          {
                              PictureBox NewBox = new PictureBox();
                              NewBox.Size = new Size(25, 25);
                              NewBox.BorderStyle = BorderStyle.FixedSingle;
                              NewBox.BackColor = BoxColor;
                              WhichList.Add(new PictureBox());
                          }
                      }
              
                      void PlaceBoxes(List<PictureBox> WhichList, Control Where)
                      {
                          for (int Index = 0; Index < WhichList.Count; Index++)
                          {
                              Point NewLocation = new Point(
                                  (Index * horizontalspacing) + 30,
                                  (Index * verticalspacing) + 30);
              
                              Where.Controls.Add(WhichList[Index]);
                              WhichList[Index].Location = NewLocation;// Set it at the time of placement, not creation
                              WhichList[Index].BringToFront();
                          }
                      }
              
                      // generate a random number
                      private int RandomNumber(int min, int max)
                      {
                          Random random = new Random(DateTime.Now.Second); // Seed with a somewhat random choice
                          return random.Next(min, max);
                      }
              
                      void SetupGameboard()
                      {
                          TopBoxes.Clear();
                          BottomBoxes.Clear();
              
                          // Disconnect events so we don't react to new Picture being added during setup
                          splitContainer2.Panel1.ControlAdded -= new ControlEventHandler(Panel1_ControlAdded);
                          splitContainer2.Panel2.ControlAdded -= new ControlEventHandler(Panel2_ControlAdded);
              
              
                          GenerateBoxes(TopBoxes, 50, Color.Green);
                          GenerateBoxes(BottomBoxes, 50, Color.Red);
                          PlaceBoxes(TopBoxes, splitContainer2.Panel1);
                          PlaceBoxes(BottomBoxes, splitContainer2.Panel2);
              
                          pictureBox1.Location = new Point(45, 70);// Move to start position
              
                          // Connect to events so we react to the Tardis moving into this space during play
                          splitContainer2.Panel1.ControlAdded += new ControlEventHandler(Panel1_ControlAdded);
                          splitContainer2.Panel2.ControlAdded += new ControlEventHandler(Panel2_ControlAdded);
              
                          label1.Text = "Bottom remaining: " + TopBoxes.Count;
                          label2.Text = "Bottom remaining: " + BottomBoxes.Count;
                      }
              
                      // React when the Tardis enters this panel
                      void Panel1_ControlAdded(object sender, ControlEventArgs e)
                      {
                          if (TopBoxes.Count > 0)
                          {
                              TopBoxes.RemoveAt(0);
                              label1.Text = "Top remaining: " + TopBoxes.Count;
                          }
                      }
              
                      // React when the Tardis enters this panel
                      void Panel2_ControlAdded(object sender, ControlEventArgs e)
                      {
                          if (BottomBoxes.Count > 0)
                          {
                              BottomBoxes.RemoveAt(0);
                              label2.Text = "Bottom remaining: " + BottomBoxes.Count;
                          }
                      }
                      #endregion Methods
                  }
              }

              Comment

              • Dalamar437
                New Member
                • Mar 2010
                • 6

                #8
                This is awesome thanks! :)

                Comment

                • Dalamar437
                  New Member
                  • Mar 2010
                  • 6

                  #9
                  Some new issues...

                  Hi! me again!
                  Just getting back to actually implementing some of your ideas and I thank you for the taking the time to clean some things up :)
                  I did want to point out 3 things in the code you pasted above that didn’t work at first without a little more modification. And lastly I’m hoping you can share your smarts again on the new problem I’ve created for myself.

                  1. Adjusting the size and properties of the box did not work at the time of creating the boxes, they only work during box placement so I moved them as follows:
                  Code:
                  //place the picture box list
                  void PlaceBoxes(List<PictureBox> WhichList, Control Where, Color BoxColor, int xlocation, int ylocation)
                          {
                              for (int Index = 0; Index < WhichList.Count; Index++)
                              {
                                  Point NewLocation = new Point(
                                      (Index * horizontalspacing) + xlocation,
                                      (Index * verticalspacing) + ylocation);
                  
                                  Where.Controls.Add(WhichList[Index]);
                                  WhichList[Index].Location = NewLocation;// Set it at the time of placement, not creation 
                                  WhichList[Index].Size = new Size(25, 25);  //moved the code here from box creation
                                  WhichList[Index].BorderStyle = BorderStyle.FixedSingle;  //moved the code here from box creation
                                  WhichList[Index].BackColor = BoxColor;  //moved the code here from box creation
                                  WhichList[Index].BringToFront();
                              }
                          }
                  
                  //place the picture box list
                  void PlaceBoxes(List<PictureBox> WhichList, Control Where, Color BoxColor, int xlocation, int ylocation)
                          {
                              for (int Index = 0; Index < WhichList.Count; Index++)
                              {
                                  Point NewLocation = new Point(
                                      (Index * horizontalspacing) + xlocation,
                                      (Index * verticalspacing) + ylocation);
                  
                                  Where.Controls.Add(WhichList[Index]);
                                  WhichList[Index].Location = NewLocation;// Set it at the time of placement, not creation 
                                  WhichList[Index].Size = new Size(25, 25);  //moved the code here from box creation
                                  WhichList[Index].BorderStyle = BorderStyle.FixedSingle;  //moved the code here from box creation
                                  WhichList[Index].BackColor = BoxColor;  //moved the code here from box creation
                                  WhichList[Index].BringToFront();
                              }
                          }
                  2. Flip coin was not relocating the pictureBox1 to the new splitContainer location, so I added the new system.drawing. point
                  Code:
                          private void FlipCoin()
                          {
                              int randomDestination = RandomNumber(1, 100);
                  
                              if (randomDestination >= 50)
                              {
                                  splitContainer2.Panel1.Controls.Add(pictureBox1);  //add the control 
                                  pictureBox1.Location = new System.Drawing.Point(70, 40);  //move the control
                              }
                              else
                              {
                                  splitContainer2.Panel2.Controls.Add(pictureBox1); //add the control
                                  pictureBox1.Location = new System.Drawing.Point(70, 40);  //move the control
                              }
                          }

                  3. The void Panel1_ControlA dded(object sender, ControlEventArg s e) was only removing the picturebox from the list and not from the split container itself. So I added splitContainer2 .Panel1.Control s.RemoveAt(0); to the following:
                  Code:
                          // React when the Tardis enters this panel 
                          void Panel1_ControlAdded(object sender, ControlEventArgs e)
                          {
                              if (TopBoxes.Count > 0)
                              {
                                  TopBoxes.RemoveAt(0); //remove from list
                                  splitContainer2.Panel1.Controls.RemoveAt(0);  //remove from panel
                                  label1.Text = "Top remaining: " + TopBoxes.Count;
                              }
                          } 
                          // React when the Tardis enters this panel 
                          void Panel2_ControlAdded(object sender, ControlEventArgs e) 
                          { 
                              if (BottomBoxes.Count > 0) 
                              { 
                                  BottomBoxes.RemoveAt(0); //remove from list
                                  splitContainer2.Panel2.Controls.RemoveAt(0); //remove from panel
                                  label2.Text = "Bottom remaining: " + BottomBoxes.Count; 
                              } 
                          }
                  4. I’ve created a new problem when I add a 2nd set of picture boxes to the same splitContainer and expect the same Red and Green boxes to be the pictureboxes that disappear.
                  Code:
                  GenerateBoxes(WildCard, 3);
                  PlaceBoxes(WildCard,splitContainer2.Panel2, Color.Yellow, 10, 70);
                  Now when I click button one, the program is confused aobut what control to remove from the split container and apears to graviate toward the last picture box that was created. This is where I’m stuck now.
                  I’m assuming I need to get the FlipCoin() to identify the index of of picture boxes within the the list I’m dealing with within the specific list I intend to modify? So for purposes of this example, lets say I only want the green & red boxes to disapear but the yellow boxes to remain.
                  Hugely appreciate your help! :)
                  I’ve attached the updated code...
                  Attached Files

                  Comment

                  • Dalamar437
                    New Member
                    • Mar 2010
                    • 6

                    #10
                    Please ignore #2, I was wrong
                    I believe I just needed a .bringtoFront() ;

                    Comment

                    Working...