Skip to content

Introduce ControlExtensions to simplify frequently needed iterating tasks #12543

Description

@KlausLoeffelmann

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

public static IEnumerable<Control> ChildControls(this Control control)
public static IEnumerable<T> ChildControls<T>(this Control control) where T : Control
public static Control FirstChild(this Control control, Func<Control, bool>? predicate = default)
public static T FirstChild<T>(this Control control, Func<T, bool>? predicate = default) where T : Control
public static T? FirstChildOrDefault<T>(this Control control, Func<T, bool>? predicate = default) where T : Control
public static IEnumerable<Control> AscendantControls(this Control control)
public static IEnumerable<T> AscendantControls<T>(this Control control, Func<Control, bool>? predicate = default) where T : Control
public static Control FirstAscendant(this Control control, Func<Control, bool>? predicate = default)
public static Control? FirstAscendantOrDefault(this Control control, Func<Control, bool>? predicate = default)
public static T FirstAscendant<T>(this Control control, Func<T, bool>? predicate = default) where T : Control
public static T? FirstAscendantOrDefault<T>(this Control control, Func<T, bool>? predicate = default) where T : Control
public static IEnumerable<Control> DescendantControls(this Control control)
public static IEnumerable<T> DescendantControls<T>(this Control control, Func<Control, bool>? predicate = default) where T : Control
public static Control FirstDescendant(this Control control, Func<Control, bool>? predicate = default)
public static T FirstDescendant<T>(this Control control, Func<T, bool>? predicate = default) where T : Control
public static Control? FirstDescendantOrDefault(this Control control, Func<Control, bool>? predicate = default)
public static T? FirstDescendantOrDefault<T>(this Control control, Func<T, bool>? 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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

🚧 work in progressWork that is current in progressapi-suggestion(1) Early API idea and discussion, it is NOT ready for implementation

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions