我的asp页面中有45个下拉列表。我可以将一些方法应用于所有这些下拉菜单。为了便于使用,是否可以将它们转换为一系列下拉列表?
答案 0 :(得分:2)
我会使用递归来查找页面上的所有下拉列表。基于此post,它将类似于:
public static List<T> FindControls<T>(System.Web.UI.ControlCollection Controls) where T : class
{
List<T> found = new List<T>();
FindControls<T>(Controls, found);
return found;
}
private static void FindControls<T>(System.Web.UI.ControlCollection Controls, List<T> found) where T : class
{
if (Controls != null && Controls.Count > 0)
{
for (int i = 0; i < Controls.Count; i++)
{
if (Controls[i] is T)
{
found.add(Controls[i] as T);
}
else
FindControl<T>(Controls[i].Controls, found);
}
}
}
获得下拉列表后,您可以应用您认为合适的任何方法。
答案 1 :(得分:1)
使用Linq to Objects,Extension方法和泛型,我们可以非常简洁:
var DropDowns = FindAllControlsByType<DropDownList>(MyBaseControlArray);
public static IEnumerable<Control> FindAllControlsByType<T>(IEnumerable<Control> MyCollection) where T : class
{
return MyCollection.Cast<Control>().Descendants(d => d.Controls.Cast<Control>()).Where(l => l.GetType().Equals(typeof(T)));
}
static public class LinqExtensions
{
static public IEnumerable<T> Descendants<T>(this IEnumerable<T> source,
Func<T, IEnumerable<T>> DescendBy)
{
foreach (T value in source)
{
yield return value;
foreach (T child in DescendBy(value).Descendants<T>(DescendBy))
{
yield return child;
}
}
}
}
我一直在考虑使这一切都更通用,所以这里是一个完全通用的解决方案,它将从指定的起点遍历一个对象图,提取给定类型的所有元素。
public static class Utils
{
public static IEnumerable<IEnumerable<T>> GetCollections<T>(object obj)
{
if (obj == null) throw new ArgumentNullException("obj");
var type = obj.GetType();
var res = new List<IEnumerable<T>>();
foreach (var prop in type.GetProperties())
{
// is IEnumerable<T>?
if (typeof(IEnumerable<T>).IsAssignableFrom(prop.PropertyType))
{
var get = prop.GetGetMethod();
if (!get.IsStatic && get.GetParameters().Length == 0) // skip indexed & static
{
var collection = (IEnumerable<T>)get.Invoke(obj, null);
if (collection != null) res.Add(collection);
}
}
}
return res;
}
public static IEnumerable<V> FindAllControlsByType<V, T>(V MyCollection) where T : class
{
return Utils.GetCollections<V>(MyCollection).Descendants(d => d).Where(l => typeof(T).IsAssignableFrom(l.GetType()));
}
}
static public class LinqExtensions
{
static public IEnumerable<T> Descendants<T>(this IEnumerable<IEnumerable<T>> source,
Func<IEnumerable<IEnumerable<T>>, IEnumerable<IEnumerable<T>>> DescendBy)
{
foreach (IEnumerable<T> collection in source)
{
foreach (T value in collection)
{
yield return value;
foreach (T child in DescendBy(Utils.GetCollections<T>(value)).Descendants<T>(DescendBy))
{
yield return child;
}
}
}
}
}
我们可以使用:
来调用它var DropDowns = Utils.FindAllControlsByType<Control, DropDownList>(BaseControl);
基本上,这两种类型是基类和要提取的特定子类。您将注意到该进程标识了基类的每个实例中包含的基类的所有集合。这意味着我们不会将Controls
作为集合绑定,并且可以在其他结构中使用它。欢迎任何额外的优化。