Search code examples
c#controlsflowlayoutpanel

Remove controls of flowlayoutpanel and recreating it in C#


I had been experimenting on writing a code to generate images inside a FlowLayoutPanel.
This is what i had done so far, when i click on a button for the first time (by using a checkboxes - read in number of images to open), it will generate the images, when i click on the button on second try, it will not update the flowlayoutpanel.

Even though i tried to remove the controls inside the FlowLayoutPanel, it still doesn't show the second try of the images.

This is the code snippet of the method:

FlowLayoutPanel fwPanel = null;

private void btnOpenFile_Click(object sender, EventArgs e)
{
    //if there is content inside the flowpanel, dump it
    if (fwPanel != null)
    {
        listOfFile.Clear();
    }

    //create a new FLP
    fwPanel = new FlowLayoutPanel();
    int panelWidth = width * 4 + 50;
    int panelHeight = height * 4 + 50;
    fwPanel.Size = new Size(panelWidth, panelHeight);
    fwPanel.Location = new Point(0, 0);
    this.Controls.Add(fwPanel);

    //each checked item would be stored into an arraylist
    foreach(object itemChecked in clbFile.CheckedItems)
    {
        listOfFile.Add((clbFile.Items.IndexOf(itemChecked)+1).ToString());
    }

    int noOfCheckedFile = listOfFile.Count;
    PictureBox[] listOfPicture = new PictureBox[noOfCheckedFile];
    int positionX = 0, positionY = 0;
    int maxPaddingX = (width * MATRIX_SIZE) - 1;
    int maxPaddingY = (height * MATRIX_SIZE) - 1;

    //dynamically create images.
    for (int i = 0; i < noOfCheckedFile; i++)
    {
        listOfPicture[i] = new PictureBox();
        listOfPicture[i].Image = resizeImage((Image)show_picture(Convert.ToInt32(listOfFile[i])), new Size(width, height));
        listOfPicture[i].Size = new Size(width, height);

        if (positionX > maxPaddingX)
        {
            positionX = 0;
            positionY += height;
        }

        if (positionY > maxPaddingY)
        {
            positionY = 0;
        }

        listOfPicture[i].Location = new Point(positionX,positionY);
        listOfPicture[i].Visible = true;
        fwPanel.Controls.Add(listOfPicture[i]);

        positionX += width;
    }
}


show_picture is a method that takes in and integer and returns a bitmap image.
listOfFile is to trace which file to return.
listOfPicture is to store each images.

i tried replacing this lines

//if there is content inside the flowpanel, dump it
if (fwPanel != null)
{
    listOfFile.Clear();
}

i have added this line into it, when i do a second click, everything just gone missing, but this is not what i want, because it does not re-populating the FlowLayoutPanel.

if (fwPanel != null)
{
    fwPanel.SuspendLayout();

    if (fwPanel.Controls.Count > 0)
    {
        for (int i = (fwPanel.Controls.Count - 1); i >= 0; i--)
        {
             Control c = fwPanel.Controls[i];
             c.Dispose();
        }
        GC.Collect();
    }

    fwPanel.ResumeLayout();
    listOfFile.Clear();
}

I also tried this, but on second click, nothing will happen.

if (fwPanel != null)
{
    List<Control> listControls = fwPanel.Controls.Cast<Control>().ToList();

    foreach (Control control in listControls)
    {
        fwPanel.Controls.Remove(control);
        control.Dispose();
    }

    listOfFile.Clear();
}

I wonder if i miss out anything, can someone enlighten me on what did i miss out ? Or guide me for the best practice of doing this.


Solution

  • as Suggested, i shifted the creation outside (credit to Sinatr for spotting it)

    FlowLayoutPanel fwPanel = new FlowLayoutPanel();
    
    private void createFLP()
        {
            int panelWidth = width * 4 + 50;
            int panelHeight = height * 4 + 50;
            fwPanel.Size = new Size(panelWidth, panelHeight);
            fwPanel.Location = new Point(0, 0);
            this.Controls.Add(fwPanel);
        }
    

    that solves the nothing happen part. Followed by using this to remove controls

    if (fwPanel != null)
    {
        List<Control> listControls = fwPanel.Controls.Cast<Control>().ToList();
    
        foreach (Control control in listControls)
        {
            fwPanel.Controls.Remove(control);
            control.Dispose();
        }
    
        listOfFile.Clear();
    }
    

    and everything works like a charm, hope that this answer will be able to help others who are facing the same problem too.