[.NET]GridView 抓控制項的值 part2

  • 22556
  • 0

[.NET]GridView 抓控制項的值 part2

今天實作ASP.NET 4.0 專題實務[I] GridView抓控制項值的練習(有修改GridView-改成樣版=>加TemplateField),

內容:當GridView被按下「編輯」的命令欄位時,進入編輯模式後,修改每一個欄位的值,在按下「更新」後抓到被修改後的值。

跟part 1要做的動作一樣,只是差別在抓值的做法

  
假設Grid欄位有id,title
image_thumb2
 
點編輯
 image_thumb5
點更新後結果
image_thumb6
 

ASPX

          <Columns>
                <asp:TemplateField HeaderText="id" InsertVisible="False" SortExpression="id">
                    <EditItemTemplate>
                        <asp:Label ID="Label1" runat="server" Text='<%# Eval("id") %>'></asp:Label>
                    </EditItemTemplate>
                    <ItemTemplate>
                        <asp:Label ID="Label1" runat="server" Text='<%# Bind("id") %>'></asp:Label>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="title" SortExpression="title">
                    <EditItemTemplate>
                        <asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("title") %>'></asp:TextBox>
                    </EditItemTemplate>
                    <ItemTemplate>
                        <asp:Label ID="Label2" runat="server" Text='<%# Bind("title") %>'></asp:Label>
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
 
這裡就看得出來跟上一個例子就有不一樣了
從原本的BoundField變成TemplateField 

而在個別的ItemTemplate裡就會產生控制項了

所以當轉換TemplateField 後就可以利用FindControl的方式抓取傳入該ID的控制項了

只是要注意一下就是這裡的ID指的是Client端的ID,而非Server上的ID 控制項上的ID(感謝提醒)

所以當是動態產生控制項的時候,

傳入的ID值要傳入產生後Client端的ID

另MSDN有提到一段很重要的一句話:「在目前的命名容器搜尋指定的伺服器控制項

Searches the current naming container for the specified server control.

image_thumb

 

也就是說只能找到第一層的子控制項,

所以用FindControl則要先找到該控制項的命名容器(Naming container)

像這裡要找GridView裡某一列裡的控制項(Ex. TextBox1)

就得先找到那一列再使用FindControl才能真正找到,程式如下

 

C#
    protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
    {
        Label lb = (Label) GridView1.Rows[e.RowIndex].FindControl("Label1");
        Response.Write("id=" + lb.Text);
        Response.Write("<br>選取的索引鍵為" + GridView1.DataKeys[e.RowIndex].Value.ToString());
        TextBox tb = new TextBox();
        tb = (TextBox)GridView1.Rows[e.RowIndex].FindControl("TextBox1");
        Response.Write("<br> title=" + tb.Text);
        Response.End();
    }
 

所以要用GridView1.Rows[e.RowIndex]去做FindControl(控制項ID)
而不能直接用GridView1.FindControl("Label1")
因為GridView1下一層是Row,而不是Row裡面的Label
如果直接在GridView1下找Label1就會找不到
發生以下的錯誤
 
C#
 

    protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
    {
        Label lb = (Label) GridView1.FindControl("Label1");        //直接在GridView1下找Label1
        Response.Write("id=" + lb.Text);
        Response.Write("<br>選取的索引鍵為" + GridView1.DataKeys[e.RowIndex].Value.ToString());
        TextBox tb = new TextBox();
        tb = (TextBox)GridView1.Rows[e.RowIndex].FindControl("TextBox1");
        Response.Write("<br> title=" + tb.Text);
        Response.End();
    }
 
 
image_thumb8
 
 
這裡將找到的控制項丟給lb
但是因為找不到
所以在取lb的屬性值時
就發生NullReferenceException的例外了
 
另外 .NET 魔法學院有提供一個很好用的函式 遞迴方式的 FindControl
 

整理一下重點:
1、FindControl:在目前的命名容器搜尋指定的伺服器控制項
 
 
參考資料:ASP.NET 4.0 專題實務[I] 實戰入門篇
   MSDN