Introduce `ControlExtensions` to simplify frequently needed iterating tasks
- Dominant language
- C#
- Stars
- 4.9k
- Forks
- 1.1k
- Avg merge
- 20h 23m
- Merged PRs (30d)
- 103
Description
### Background and motivation
There are a lot of cases, where we need to recursively traverse through the controls collection (up or down), to either process a collection of certain controls or find a specific control in the tree. This is, where the typical WinForms developer invents the wheel for their apps for the gazilion-th time.
To that end, we suggest introducing the following extension class to make those tasks super-convenient, and make sure, that we do not allocate anything during operation.
Note:
PR would be a side-product of one of the .NET Conf Demos and ready to go immediately.
@merriemcgaw, @lonitra
@JeremyKuhne: If we want to further discuss the concept of a more granular base-layout type, this API would be super-easy to adapt to that and also the perfect icing on that cake.
### API Proposal
```csharp
public static IEnumerable ChildControls(this Control control)
public static IEnumerable ChildControls(this Control control) where T : Control
public static Control FirstChild(this Control control, Func? predicate = default)
public static T FirstChild(this Control control, Func? predicate = default) where T : Control
public static T? FirstChildOrDefault(this Control control, Func? predicate = default) where T : Control
public static IEnumerable AscendantControls(this Control control)
public static IEnumerable AscendantControls(this Control control, Func? predicate = default) where T : Control
public static Control FirstAscendant(this Control control, Func? predicate = default)
public static Control? FirstAscendantOrDefault(this Control control, Func? predicate = default)
public static T FirstAscendant(this Control control, Func? predicate = default) where T : Control
public static T? FirstAscendantOrDefault(this Control control, Func? predicate = default) where T : Control
public static IEnumerable DescendantControls(this Control control)
public static IEnumerable DescendantControls(this Control control, Func? predicate = default) where T : Control
public static Control FirstDescendant(this Control control, Func? predicate = default)
public static T FirstDescendant(this Control control, Func? predicate = default) where T : Control
public static Control? FirstDescendantOrDefault(this Control control, Func? predicate = default)
public static T? FirstDescendantOrDefault(this Control control, Func? predicate
public static Control Root(this Control control)
```
### API Usage
Self-Explaining.
### Alternative Designs
_No response_
### Risks
None.
### Will this feature affect UI controls?
Only easier usage and help with discoverability.
Contributor guide
Assessment
This issue has not been assessed yet.