Reputation: 137
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
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
Cast<Control>
you can use OfType<YourUserControl>
.OrderBy(x => x.Top)
you can use OrderByDescending(x => container.Controls.IndexOf(x))
container.ScrollControlIntoView(top);
or the bottom control container.ScrollControlIntoView(bottom);
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
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
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