Repeater 模板中查找子控件


前言:對於Repeater控件,相信從事NETWeb開發的同仁們再熟悉不過了。因其呈現方式和Literal一樣,並不在前端生成任何表單標簽元素,所以屬於比較輕量級的控件。不過青睞於Repeater的主要原因還是其表單布局的自由性和易控性。下面就來總結一下使用Repeater常用的功能:子控件的查找。

一、在ItemTemplateAlternatingItemTemplate中查找

這個估計大家應該都知道,不過這里還是要列一下,代碼如下:

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就是這兩種類型(注意:如果是通過其他方式查找,則可能必須加此判斷)。

二、在HeaderTemplateFooterTemplate中查找

根據上面提到的,通過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.還請瀏覽過本貼的大俠,雁過留聲,給予指點。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM