I am trying to find an elegant way to get controls on a Windows Forms form by name. For example:
MyForm.GetControl "MyTextBox"
...
But this has to make sure it goes through all the controls recursively.
What's the most elegant way to implement this using LINQ?
Windows Forms controls are reusable components that encapsulate user interface functionality and are used in client-side, Windows-based applications. Not only does Windows Forms provide many ready-to-use controls, it also provides the infrastructure for developing your own controls.
EntityID == list. EntityID); If you have a list of entities and you want to find any records that exist in the database that don't exist in the list you can do this: var extraitems = db.
The Any operator is used to check whether any element in the sequence or collection satisfy the given condition. If one or more element satisfies the given condition, then it will return true. If any element does not satisfy the given condition, then it will return false.
Select() takes each source element, transforms it, and returns a sequence of the transformed values.
Thanks to C# 3 there are many elegant solutions. This one doesn't use LINQ query operators; it uses lambdas and delegates.
This filters all controls for given criteria (can filter against multiple criteria). Returns multiple matches. It allows for more than name detection.
/// <summary>
/// Recurses through all controls, starting at given control,
/// and returns an array of those matching the given criteria.
/// </summary>
public Control[] FilterControls(Control start, Func<Control, bool> isMatch) {
var matches = new List<Control>();
Action<Control> filter = null;
(filter = new Action<Control>(c => {
if (isMatch(c))
matches.Add(c);
foreach (Control c2 in c.Controls)
filter(c2);
}))(start);
return matches.ToArray();
}
It's quite flexible as far as usage
Control[] foundControls = null;
// Find control with Name="tabs1".
foundControls = FilterControls(this,
c => c.Name != null && c.Name.Equals("tabs1"));
// Find all controls that start with ID="panel*...
foundControls = FilterControls(this,
c => c.Name != null && c.Name.StartsWith("panel"));
// Find all Tab Pages in this form.
foundControls = FilterControls(this,
c => c is TabPage);
Console.Write(foundControls.Length); // is an empty array if no matches found.
Extension methods add an heir of elegancy to applications also.
The exact same logic can be injected into an extension method like so.
static public class ControlExtensions {
static public Control[] FilterControls(this Control start, Func<Control, bool> isMatch) {
// Put same logic here as seen above (copy & paste)
}
}
Extension usage is:
// Find control with Name="tabs1" in the Panel.
panel1.FilterControls(c => c.Name != null && c.Name.Equals("tabs1"));
// Find all panels in this form
this.FilterControls(c => c is Panel);
null
Calls the first extension method (see above) to get all matching controls, then returns the first one in the matches, otherwise null if the match list is empty.
This isn't efficient because it iterates over all controls even after finding the first match - but just playing around here for the sake of SO comments.
static public Control FilterControlsOne(this Control start, Func<Control, bool> isMatch) {
Control[] arrMatches = ControlExtensions.FilterControls(start, isMatch);
return arrMatches.Length == 0 ? null : arrMatches[0];
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With