FindControl 找控件,方法总结

mac2022-06-30  25

FindControl 是 ASP.NET 工程師十分常用的 Method,但初學者應該常常會遇到使用 FindControl 卻找不到 Control 的狀況!

首先,在 ASP.NET 中有所謂 NamingContainer (命名容器) 的觀念,在使用 Data-bound Control ( 資料控制項 ) 時,會用到 ItemTemplate 之類(ITemplate)的標籤,裡面還會包含許多 Control,這些包含在 Template 裡面的 Control 其實是跟原本頁面(Page)中的控制項是不同階層的!而這些被 ITemplate 包含的 Controls 其 NamingContainer 就是這個 Data-bound Control 的每一個 ItemTemplate!

在這種情況下,若要在 Code behind 中使用 Page.FindControl 想直接找到這些 Data-bound Control 的 Template 中的 Control 的話,就沒辦法直接用 Control ID 找到這個 Control。

例如:

 

[code:html]         < asp:repeater ID ="Repeater1" runat ="server" >             < ItemTemplate >                 < asp:TextBox ID ="TextBox1" runat ="server" Text ="Text on row" />             </ ItemTemplate >         </ asp:repeater > [/code]

在 Code behind 的 Page_Load 事件中要尋找 Repeater1 中第一個 TextBox1 時,使用以下的程式碼就會出錯,因為找不到 TextBox1:

 

[code:c#] using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; public partial class _Default : System.Web.UI.Page {     protected void Page_Load( object sender, EventArgs e)     {         System.Collections.ArrayList a = new ArrayList();         a.Add("List 1");         a.Add("List 2");         Repeater1.DataSource = a;         Repeater1.DataBind();         TextBox txt1 = (TextBox)Page.FindControl("TextBox1");  // txt1 會是 null         Response.Write(txt1.Text); // 因為 txt1 是 null 而無法取得 txt1.Text 屬性而發生例外(Exception)     } } [/code]

如果要透過 FindControl 找到控制項的話,我是有以下 4 種技巧分享給大家:

1. 透過實做 Repeater1 的 ItemDataBound 事件來取得每一個 ItemTemplate 中 TextBox1 的控制項

這是最常見的用法!

 

[code:c#]     protected void Repeater1_ItemDataBound( object sender, RepeaterItemEventArgs e)     {         TextBox txt1 = (TextBox)e.Item.FindControl("TextBox1");         Response.Write(txt1.Text);     } [/code]

2. 透過 Repeater1.Items[0].FindControl("TextBox1") 找到第一個 ItemTemplate 中的 TextBox1 控制項

這是取得第一個 ItemTemplate 中的 TextBox1 的常見用法!

3. 透過 Page.FindControl("Repeater1$ctl00$TextBox1") 找到第一個 ItemTemplate 中的 TextBox1 控制項

 這算是使用 FindControl 的小技巧,因為 ASP.NET 的控制項如果沒有 ID 的話,都是從 ctl00 開始算起的。  因為 ItemTemplate 是 NamingContainer 但卻沒有設定 ID,所以第一筆就是 ctl00 第二筆就是 ctl01 依此類推。

4. 透過 FindControl<TextBox>("TextBox1") 找到整個頁面中第一個出現的 TextBox1 控制項(不一定在 Repeater1 裡面)

這是透過一個自訂的泛型遞迴方法(Generic Recursive Method)達成。   要使用這段程式比需將以下的程式碼複製到你的頁面的類別(Code behind)中。 ( 以下程式碼參考自:http://blogs.interfacett.com/michael-palermo/2007/4/13/recursive-findcontrolt.html  )

[code:c#]     public T FindControl<T>( string id) where T : Control     {         return FindControl<T>(Page, id);     }

    public static T FindControl<T>(Control startingControl, string id) where T : Control     {         // 取得 T 的預設值,通常是 null         T found = default (T);

        int controlCount = startingControl.Controls.Count;

        if (controlCount > 0)         {             for (int i = 0; i < controlCount; i++)             {                 Control activeControl = startingControl.Controls[i];                 if (activeControl is T)                 {                     found = startingControl.Controls[i] as T;                     if (string .Compare(id, found.ID, true ) == 0) break ;                     else found = null ;                 }                 else                 {                     found = FindControl<T>(activeControl, id);                     if (found != null ) break ;                 }             }         }         return found;     } [/code]

转载于:https://www.cnblogs.com/deepwishly/archive/2010/02/28/2551284.html

最新回复(0)