【发布时间】:2010-08-31 22:01:54
【问题描述】:
有没有一种方法可以使用 linq 来获取网页中的文本框列表,而不管它们在树层次结构或容器中的位置如何。所以不是循环遍历每个容器的 ControlCollection 来查找文本框,而是在 linq 中做同样的事情,也许在单个 linq 语句中?
【问题讨论】:
标签: asp.net linq recursion web-controls
有没有一种方法可以使用 linq 来获取网页中的文本框列表,而不管它们在树层次结构或容器中的位置如何。所以不是循环遍历每个容器的 ControlCollection 来查找文本框,而是在 linq 中做同样的事情,也许在单个 linq 语句中?
【问题讨论】:
标签: asp.net linq recursion web-controls
我见过的一种技术是在 ControlCollection 上创建一个扩展方法,该方法返回一个 IEnumerable ... 类似这样:
public static IEnumerable<Control> FindAll(this ControlCollection collection)
{
foreach (Control item in collection)
{
yield return item;
if (item.HasControls())
{
foreach (var subItem in item.Controls.FindAll())
{
yield return subItem;
}
}
}
}
处理递归。然后你可以像这样在你的页面上使用它:
var textboxes = this.Controls.FindAll().OfType<TextBox>();
这将为您提供页面上的所有文本框。您可以更进一步,构建处理类型过滤的扩展方法的通用版本。它可能看起来像这样:
public static IEnumerable<T> FindAll<T>(this ControlCollection collection) where T: Control
{
return collection.FindAll().OfType<T>();
}
你可以这样使用它:
var textboxes = this.Controls.FindAll<TextBox>().Where(t=>t.Visible);
【讨论】:
如果您的页面有一个母版页并且您知道内容占位符名称,那么这很容易。我做了类似的事情,但使用网络面板
private void SetPanelVis(string PanelName)
{
Control topcontent = Form.FindControl("MainContent");
foreach (Control item in topcontent.Controls.OfType<Panel>())
{
item.Visible = (item.ID == RadioButtonList1.SelectedValue);
}
}
【讨论】:
您将需要递归来遍历所有控件的所有子控件。除非出于某种原因您必须使用 LINQ 来实现它(我假设您的意思是 lambdas),否则您可以尝试使用 this approach using Generics。
【讨论】:
http://www.dotnetperls.com/query-windows-forms 提供了我找到的关于这个问题的最佳答案集。我选择了 LINQ 版本:
/// <summary>
/// Use a LINQ query to find the first focused text box on a windows form.
/// </summary>
public TextBox TextBoxFocusedFirst1()
{
var res = from box in this.Controls.OfType<TextBox>()
where box.Focused == true
select box;
return res.First();
}
【讨论】: