Ani*_*cho 31 c# asp.net webforms
我一直在思考如何在页面上获取所有控件,然后在相关问题中对它们执行任务:
我需要可以扫描页面的代码,获取所有DropDownList控件并将它们返回到列表中.
我目前不得不编辑每个单独的控件,我宁愿能够动态循环每个控件来执行我的任务.
Ste*_*e B 59
检查我以前的SO答案.
基本上,我们的想法是使用以下方法包装迭代控件集合的递归:
private void GetControlList<T>(ControlCollection controlCollection, List<T> resultCollection)
where T : Control
{
foreach (Control control in controlCollection)
{
//if (control.GetType() == typeof(T))
if (control is T) // This is cleaner
resultCollection.Add((T)control);
if (control.HasControls())
GetControlList(control.Controls, resultCollection);
}
}
Run Code Online (Sandbox Code Playgroud)
并使用它:
List<DropDownList> allControls = new List<DropDownList>();
GetControlList<DropDownList>(Page.Controls, allControls )
foreach (var childControl in allControls )
{
// call for all controls of the page
}
Run Code Online (Sandbox Code Playgroud)
[2013年11月26日编辑]:这是实现这一目标的更优雅方式.我编写了两个扩展方法,可以在两个方向上遍历控制树.这些方法以更Linq的方式编写,因为它产生了一个可枚举的:
/// <summary>
/// Provide utilities methods related to <see cref="Control"/> objects
/// </summary>
public static class ControlUtilities
{
/// <summary>
/// Find the first ancestor of the selected control in the control tree
/// </summary>
/// <typeparam name="TControl">Type of the ancestor to look for</typeparam>
/// <param name="control">The control to look for its ancestors</param>
/// <returns>The first ancestor of the specified type, or null if no ancestor is found.</returns>
public static TControl FindAncestor<TControl>(this Control control) where TControl : Control
{
if (control == null) throw new ArgumentNullException("control");
Control parent = control;
do
{
parent = parent.Parent;
var candidate = parent as TControl;
if (candidate != null)
{
return candidate;
}
} while (parent != null);
return null;
}
/// <summary>
/// Finds all descendants of a certain type of the specified control.
/// </summary>
/// <typeparam name="TControl">The type of descendant controls to look for.</typeparam>
/// <param name="parent">The parent control where to look into.</param>
/// <returns>All corresponding descendants</returns>
public static IEnumerable<TControl> FindDescendants<TControl>(this Control parent) where TControl : Control
{
if (parent == null) throw new ArgumentNullException("control");
if (parent.HasControls())
{
foreach (Control childControl in parent.Controls)
{
var candidate = childControl as TControl;
if (candidate != null) yield return candidate;
foreach (var nextLevel in FindDescendants<TControl>(childControl))
{
yield return nextLevel;
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
由于this关键字,这些方法是扩展方法,可以简化代码.
例如,要查找DropDownList页面中的所有内容,您只需调用:
var allDropDowns = this.Page.FindControl<DropDownList>();
Run Code Online (Sandbox Code Playgroud)
由于使用了yield关键字,并且因为Linq足够智能来推迟执行枚举,所以可以调用(例如):
var allDropDowns = this.Page.FindDescendants<DropDownList>();
var firstDropDownWithCustomClass = allDropDowns.First(
ddl=>ddl.CssClass == "customclass"
);
Run Code Online (Sandbox Code Playgroud)
只要First满足方法中的谓词,枚举就会停止.整个控制树不会走路.
mar*_*rko 15
foreach (DropDownList dr in this.Page.Form.Controls.OfType<DropDownList>())
{
}
Run Code Online (Sandbox Code Playgroud)
小智 5
有这个问题,虽然我发现Steve B的答案很有用,但我想要一个扩展方法,所以重新考虑它:
public static IEnumerable<T> GetControlList<T>(this ControlCollection controlCollection) where T : Control
{
foreach (Control control in controlCollection)
{
if (control is T)
{
yield return (T)control;
}
if (control.HasControls())
{
foreach (T childControl in control.Controls.GetControlList<T>())
{
yield return childControl;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个递归版本,它返回所请求类型的控件集合,而不是使用另一个参数:
using System.Collections.Generic;
using System.Web.UI;
// ...
public static List<T> GetControls<T>(ControlCollection Controls)
where T : Control {
List<T> results = new List<T>();
foreach (Control c in Controls) {
if (c is T) results.Add((T)c);
if (c.HasControls()) results.AddRange(GetControls<T>(c.Controls));
}
return results;
}
Run Code Online (Sandbox Code Playgroud)
插入您的班级(静态可选).
| 归档时间: |
|
| 查看次数: |
68650 次 |
| 最近记录: |