tony
tony

Reputation: 137

Is it possible to find which userControl are visible in a flowlayoutPanel

I have a FlowLayoutPanel that I add 50 UserControl to dynamically. The panel is positioned vertically and each user control has some labels that are read-only.

I use this.KeyPreview = true; in the form so I can use the event handler Form1_KeyUp to catch keyUp event. In this event handler, I catch the navigation buttons , , , , PageUp and PageDown.

When I click the navigation button the previous UserControl is selected in the panel and when click the next UserControl is selected. This works good.

The customer want also to be able to use PageUp and PageDown which I catch in the event handler Form1_KeyUp as I mentioned before.

I hope that I can find which UserControl that are visible. Assume UserControl with index 1,2,3,4 are visible in the panel then I can select user control at index 1 when I use PageUp and user control at index 4 when I click PageDown.

Any help is welcome.

Upvotes: 1

Views: 2305

Answers (3)

Reza Aghaei
Reza Aghaei

Reputation: 125197

You can use such code:

var controls = container.Controls.Cast<Control>().OrderBy(x => x.Top);
var visibles = controls.Where(l => container.ClientRectangle.IntersectsWith(l.Bounds));
var top = visibles.FirstOrDefault();
var bottom = visibles.LastOrDefault();

In above code, I first ordered controls of container by Top of them. Then using IntersectsWith I found those controls that their bounds has intersection with client rectangle of container which means those controls are visible.

Since the list is ordered by Top property of controls, the first item is the visible one at top of container and the last item is the visible one at bottom of container.

Note

  • Instead of Cast<Control> you can use OfType<YourUserControl>.
  • Instead of OrderBy(x => x.Top) you can use OrderByDescending(x => container.Controls.IndexOf(x))
  • You can bring the top control into view using container.ScrollControlIntoView(top); or the bottom control container.ScrollControlIntoView(bottom);
  • If you have a FlowLayoutPanel with AutoScroll=True and FlowDirection=TopDown and WrapContents=False then you can use a Panel instead, just when adding user controls, set Dock=Top for them.

Upvotes: 2

Zag Gol
Zag Gol

Reputation: 1076

If by visible you mean, Visible property is true, use 'Shannon Holsinger' answer:

If you mean at least one pixel of a control can be seen, loop on all controls, and use this answer for checking if the control is visible

C# winform check if control is physicaly visible

Upvotes: 0

Pepernoot
Pepernoot

Reputation: 3609

if I understand you correctly , this is what you meant

 public List<Control> GetvisibleControls(Control parent)
            {
                List<Control> returnList = new List<Control>();
                foreach(Control child in parent.Controls)
                {
                    if (child.Location.X < parent.Width && child.Location.Y < parent.Height)
                        returnList.Add(child);
                }
                return returnList;
            }

Upvotes: 0

Related Questions