0

Hello everyone I'm trying to search for control in flowlayoutpanel by taking input from textBox text and determine if that input is equal to the panel control label text, but when I typed in input on the textBox nothing happened.

This is how the panel look like

generated panel

The created panel consists of several control: Label, Picturebox, Button, 2 labels. And i want to keep all of the controls as well when the user searched for the panel based on the label text.

This is how the panel (and labels) was created:

                            int top = 275;
                            int h_p = 100;
                            var panelTxt = new Guna2Panel() {
                                Name = panName + itemCurr,
                                Width = 240,
                                Height = 262,
                                BorderRadius = 8,
                                FillColor = ColorTranslator.FromHtml("#121212"),
                                BackColor = Color.Transparent,
                                Location = new Point(600, top)
                            };

                            top += h_p;
                            flowLayoutPanel1.Controls.Add(panelTxt);
                            var mainPanelTxt = ((Guna2Panel)flowLayoutPanel1.Controls[panName + itemCurr]);

                            var textboxPic = new Guna2PictureBox();
                            mainPanelTxt.Controls.Add(textboxPic);
                            textboxPic.Name = "TxtBox" + itemCurr;
                            textboxPic.Width = 240;
                            textboxPic.Height = 164;
                            textboxPic.BorderRadius = 8;
                            textboxPic.SizeMode = PictureBoxSizeMode.CenterImage;
                            textboxPic.Enabled = true;
                            textboxPic.Visible = true;

                            Label titleLab = new Label();
                            mainPanelTxt.Controls.Add(titleLab);
                            titleLab.Name = "LabVidUp" + itemCurr;
                            titleLab.Font = new Font("Segoe UI Semibold", 12, FontStyle.Bold);
                            titleLab.ForeColor = Color.Gainsboro;
                            titleLab.Visible = true;
                            titleLab.Enabled = true;
                            titleLab.Location = new Point(12, 182);
                            titleLab.Width = 220;
                            titleLab.Height = 30;
                            titleLab.Text = getName;

                            titlePanelSearch = titleLab;

                            Guna2Button remButTxt = new Guna2Button();
                            mainPanelTxt.Controls.Add(remButTxt);
                            remButTxt.Name = "RemTxtBut" + itemCurr;
                            remButTxt.Width = 39;
                            remButTxt.Height = 35;
                            remButTxt.FillColor = ColorTranslator.FromHtml("#4713BF");
                            remButTxt.BorderRadius = 6;
                            remButTxt.BorderThickness = 1;
                            remButTxt.BorderColor = ColorTranslator.FromHtml("#232323");
                            remButTxt.Image = FlowSERVER1.Properties.Resources.icons8_garbage_66;
                            remButTxt.Visible = true;
                            remButTxt.Location = new Point(189, 218);
                            remButTxt.BringToFront();

I tried to loop through the controls in flowlayoutpanel and tried to search for titleLab label inside the created panel which what I'll use to search for the panel.

This is the textBox input:

private void guna2TextBox5_TextChanged(object sender, EventArgs e) {
         

        foreach(Control c in flowLayoutPanel1.Controls) {
            if(c.GetType() == typeof(Label)) {
                Label defineLabel = (Label)c;
                if(!defineLabel.Text.ToLower().Contains(guna2TextBox5.Text.ToLower())) {
                    flowLayoutPanel1.Controls.Remove(c);
                }
            }
        }
    }

I type in 'Untitled' on the textBox for testing but nothings happened the panel just stays how it was before I typed anything in while I was expecting for panel with label text 'Untitled' to show up and remove the other panels with label that does not equal to the textBox input.

Refer links:

Search controls in a FlowLayoutPanel

how can i search Controls in flow Layout panel?

IVSoftware
  • 5,732
  • 2
  • 12
  • 23
  • You are looping the FLP controls only, the panels. You need inner loop to get the `c.Controls` collections where the labels belong. If the panels also contain containers with children, then you need a _recursive_ routine to loop the _tree_. – dr.null Mar 11 '23 at 09:13
  • @dr.null `You need inner loop to get the c.Controls collections where the labels belong` That's exactly where I'm stuck at right now I don't know how to implement that do you have example code? – HenryCollin Mar 11 '23 at 10:00
  • 1
    https://stackoverflow.com/questions/3419159/how-to-get-all-child-controls-of-a-windows-forms-form-of-a-specific-type-button – Hans Passant Mar 11 '23 at 12:57
  • Hans and Null while I understand that the code in the post is failing for "not" [iterating the control tree](https://stackoverflow.com/a/62174482/5438626) the thing I _don't_ get is why the idea of iterating every control in every panel is being entertained as a good way to fulfill on the actual intent of filtering the flow layout panel. It's not! – IVSoftware Mar 11 '23 at 14:39
  • 1
    @IVSoftware ah, whatever you say. Calm down, slow down, read carefully, understand the problem, then suggest a solution if you have one. Maybe your solution is right and we are wrong. Nothing wrong with that. Just wait for the OP to tell. [Btw](https://stackoverflow.com/users/14171304/dr-null?tab=votes&sort=downvote). RELAX :) – dr.null Mar 11 '23 at 15:22
  • Oh I'm calm - just me and the elephant in the room over here having a smoke. Just saying this could be considered an [XY Problem](https://meta.stackexchange.com/a/66378) where X is the OP's stated goal to "search[...] for the panel based on the label [inside the panel] text". Recursing the control tree means 5 ops for each panel just to cull out the Labels and at least one to identify the `titleLab` to reach the goal of comparing `titleLab.Text` to the search term in `guna2TextBox5.Text`. I'm just pointing out that 7 ops is more than 1, especially at scale. – IVSoftware Mar 12 '23 at 14:17

1 Answers1

0

There are three potential problems with your code for guna2TextBox5_TextChanged1:

  1. This method is looking for Label controls in the Controls collection of flowLayoutPanel1 that are actually in the Controls collection of the Guna2Panel. As others have pointed out, interating the control tree of flow layout panel will find these labels, but not in a manner that is in any way efficient in terms of a search.
  2. Your post says you want "to search for titleLab label" specifically. The current code yields a positive match if "any" Label meets the criteria.
  3. Your method is calling Remove(c). But you say that "i want to keep all of the controls" and to do that you would want to set the Visible property of the Guna2Panel to false instead. The UI strongly implies that clicking on is how user can permanently Remove one of the panels and delete the image file.

One way to address all of these issues is to create a UserControl that would be configured to match the image you posted of "how the panel look like". This control could expose a public property TitleLabelText that will make filtering much more efficient.


user control

public partial class Guna2Panel : UserControl
{
    public Guna2Panel() => InitializeComponent();

    private FileInfo _fileInfo;
    public string FullPath
    {
        get => _fileInfo.FullName;
        set
        {
            _fileInfo = new FileInfo(value);
            Refresh();
        }
    }
    public string TitleLabelText => _fileInfo.Name;
    public DateTime Date
    {
        get => _fileInfo.LastWriteTime;
        set 
        {
            _fileInfo.LastWriteTime = value;
            Refresh();
        }
    }
    public new void Refresh() 
    {
        titleLab.Text = _fileInfo.Name;
        labelDate.Text = _fileInfo.LastWriteTime.ToShortDateString();
        var img =  Image.FromFile(FullPath);
        textboxPic.Image = img;
        // https://stackoverflow.com/a/23400751/5438626
        if (Array.IndexOf(img.PropertyIdList, 274) > -1)
        {
            var orientation = (int)img.GetPropertyItem(274).Value[0];
            switch (orientation)
            {
                case 1: break;
                case 3: img.RotateFlip(RotateFlipType.Rotate180FlipNone);   break;
                case 4: img.RotateFlip(RotateFlipType.Rotate180FlipX); break;
                case 5: img.RotateFlip(RotateFlipType.Rotate90FlipX); break;
                case 6: img.RotateFlip(RotateFlipType.Rotate90FlipNone); break;
                case 7: img.RotateFlip(RotateFlipType.Rotate270FlipX); break;
                case 8: img.RotateFlip(RotateFlipType.Rotate270FlipNone); break;
            }
            // This EXIF data is now invalid and should be removed.
            img.RemovePropertyItem(274);
        }
        base.Refresh();
    }
}

Search

This makes a more efficient search in the main form to filter the FlowLayoutPanel for matches where TitleLabelText contains guna2TextBox5.Text. It also meets the requirement "to keep all of the controls" even those that are not currently visible.

search

public partial class MainForm : Form
{
    public MainForm()
    {
        InitializeComponent();
        guna2TextBox5.TextChanged += guna2TextBox5_TextChanged;
    }
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        string folder = Path.Combine(
            Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
            "stackoverflow",
            typeof(MainForm).Assembly.GetName().Name,
            "Images");
        Directory.CreateDirectory(folder);
        foreach (var fullPath in Directory.GetFiles(folder))
        {
            flowLayoutPanel.Controls.Add(new Guna2Panel
            {
                FullPath = fullPath,
                Margin = new Padding(5),
            });
        }
    }

    private void guna2TextBox5_TextChanged(object sender, EventArgs e)
    {
        if(string.IsNullOrWhiteSpace(guna2TextBox5.Text))
        {
            foreach (var userControl in flowLayoutPanel.Controls.OfType<Guna2Panel>())
            {
                userControl.Visible = true;
            }
        }
        else
        {
            foreach (var userControl in flowLayoutPanel.Controls.OfType<Guna2Panel>())
            {
                userControl.Visible = userControl.TitleLabelText.Contains(guna2TextBox5.Text, StringComparison.OrdinalIgnoreCase);
            }
        }
    }
}
IVSoftware
  • 5,732
  • 2
  • 12
  • 23