前言:对于Repeater控件,相信从事NETWeb开发的同仁们再熟悉不过了。因其呈现方式和Literal一样,并不在前端生成任何表单标签元素,所以属于比较轻量级的控件。不过青睐于Repeater的主要原因还是其表单布局的自由性和易控性。下面就来总结一下使用Repeater常用的功能:子控件的查找。
一、在ItemTemplate和AlternatingItemTemplate中查找
这个估计大家应该都知道,不过这里还是要列一下,代码如下:
1 RepeaterItemCollection ReItems = Repeater1.Items; 2 foreach (RepeaterItem item in ReItems) 3 { 4 Label lbl = (Label)item.FindControl("Label1");//以查找Label为例,下同 5 }
这里可能有人要说了,是不是需要加Repeater1.Items的类型判断,如下判断:
1 if (item.ItemType == ListItemType.Item || item.ItemType == ListItemType.AlternatingItem) 2 { 3 foreach (RepeaterItem item in ReItems) 4 { 5 Label lbl = (Label)item.FindControl("Label1"); 6 } 7 }
在这我想说加判断没任何问题,但是不加也不会有问题,因为Repeater1.Items就是这两种类型(注意:如果是通过其他方式查找,则可能必须加此判断)。
二、在HeaderTemplate和FooterTemplate中查找
根据上面提到的,通过Repeater1.Items集合肯定是找不到了,那怎么找呢?我们知道Repeater是数据控件,是可以包含子控件的,那么自然也就有Controls属性,没错,就是他。
在HeaderTemplate中找
1 Label lbl = (Label)Repeater1.Controls[0].Controls[0].FindControl("Label1");
在FooterTemplate中找
1 Label lbl2 = (Label)Repeater1.Controls[Repeater1.Controls.Count - 1].Controls[0].FindControl("Label1");
三、在SeparatorTemplate中查找
这个答案下面找
1 RepeaterItem item; Label lbl; string msg=""; 2 for (int cnt = Repeater1.Controls.Count, i = 0; i < cnt; i++) 3 { 4 item = (RepeaterItem)Repeater1.Controls[i]; 5 lbl = (Label)item.FindControl("Label1"); 6 if (lbl == null) continue; 7 switch (item.ItemType) 8 { 9 case ListItemType.Header: msg = "Label在Header中"; break; 10 case ListItemType.Item: msg = "Label在Item" + i + "中"; break; 11 case ListItemType.AlternatingItem: msg = "Label在AlternatingItem " + i + "中"; break; 12 case ListItemType.Separator: msg = "Label在Separator" + i + "中"; break; 13 case ListItemType.Footer: msg = "Label在Footer中"; break; 14 default: break; 15 } 16 ScriptManager.RegisterStartupScript(this, this.GetType(), "" + i, "alert('" + msg + "');", true); 17 }
四、使用C#3.0的新的语言功能:扩展方法
说明:此处不为讲解扩展方法,直接上代码了,并且都配了详细的使用例子,如果有不懂得地方可以MSDN或google
1.扩展方法
说明:命名空间和类名根据实际需要自己定义
1 using System; 2 using System.Collections; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Web; 6 using System.Web.UI; 7 using System.ComponentModel; 8 namespace SignUp.Web.App_Code 9 { 10 /// <summary> 11 /// 扩展方法 12 /// </summary> 13 public static class NetExtensionFunctions 14 { 15 /// <summary> 16 /// 查找控件下的后代控件 17 /// </summary> 18 /// <param name="ctrl"></param> 19 /// <returns></returns> 20 public static IEnumerable<Control> GetChildren(this Control ctrl) 21 { 22 var children = ctrl.Controls.Cast<Control>(); 23 return children.SelectMany(GetChildren).Concat(children); 24 } 25 /// <summary> 26 /// 查找控件下指定类型的后代控件 27 /// </summary> 28 /// <typeparam name="T"></typeparam> 29 /// <param name="ctrl"></param> 30 /// <returns></returns> 31 public static List<T> FindControlsByType<T>(this Control ctrl) 32 { 33 return ctrl.GetChildren().OfType<T>().ToList<T>(); 34 } 35 /// <summary> 36 /// 查找控件下符合Predicate条件的后代控件 37 /// </summary> 38 /// <typeparam name="T"></typeparam> 39 /// <param name="ctrl"></param> 40 /// <param name="where"></param> 41 /// <returns></returns> 42 public static List<T> FindControlsByType<T>(this Control ctrl, Predicate<T> where) 43 { 44 return ctrl.GetChildren().OfType<T>().ToList<T>().FindAll(where); 45 } 46 } 47 }
2.使用扩展方法
注意:必须在使用的地方引用扩展方法所在的命名空间
1 using SignUp.Web.App_Code;
2.1使用GetChildren()扩展方法
1 IEnumerable<Control> controls = Repeater1.GetChildren(); 2 foreach (Control ctrl in controls) 3 { 4 if (ctrl is Label && ctrl.ID == "Label1") 5 { 6 ScriptManager.RegisterStartupScript(this, this.GetType(), "", "alert('找到了Label1');", true); 7 break; 8 } 9 }
2.2使用扩展方法:FindControlsByType<T>(this Control ctrl)
1 List<RepeaterItem> repeaterItems = Repeater1.FindControlsByType<RepeaterItem>(); 2 foreach (RepeaterItem item in repeaterItems) 3 { 4 if (item.ItemType == ListItemType.AlternatingItem || item.ItemType == ListItemType.Item) 5 { 6 List<Label> Labels = item.FindControlsByType<Label>(); 7 //do others... 8 } 9 }
2.3使用扩展方法:FindControlsByType<T>(this Control ctrl, Predicate<T> where)
1 List<RepeaterItem> repeaterItems = Repeater1.FindControlsByType<RepeaterItem>(x => (x.ItemType == ListItemType.Item || x.ItemType == ListItemType.AlternatingItem)); 2 foreach (RepeaterItem item in repeaterItems) 3 { 4 List<Label> Labels = item.FindControlsByType<Label>(); 5 //do others... 6 }
总结:对于Repeater相信已是老生常谈,这里我想需要留意的应该是扩展方法的应用。虽然代码量不多,但知识点可不少。如要很熟练的编写和使用扩展方法,至少要熟悉Linq编程,对泛型有较深入的理解,还有对Lambda和Delegate熟练的应用等。最后希望本文对大家有所帮助。
补充纠错:在扩展方法3中,使用了C#上下文关键字Where作为参数名,确实不宜!(感谢alert(dong)在评论中的指出);另外这位朋友还指出扩展方法里没有对NULL进行控制,下面给出两个控制
1.如果为NULL返回空集合(使用中只怕会混淆)
1 if (object.Equals(null, ctrl)) 2 return new List<Control>().AsEnumerable<Control>();
2.如果为NULL抛出异常(略显多余,NET本就会引发异常)
1 if (object.Equals(null, ctrl)) 2 throw new ArgumentNullException("Control", "未将对象引用设置到对象实例");
3.启用Try Catch机制(还是抛出异常的好)
4.还请浏览过本贴的大侠,雁过留声,给予指点。