如何獲得GridView內LinkButton的RowIndex? (.NET) (ASP.NET)

Abstract
  在.NET 1.x的DataGrid,可以在ItemCommand event的e.Item.ItemIndex獲得目前的RowIndex,但在.NET 2.0的GridView,卻無法使用這種方式在RowCommand event獲得RowIndex。

Motivation
  為什麼需要在RowCommand event獲得RowIndex呢?通常一個Table的PK或FK並不會顯示在GridView上,而會設定在DataKeyNames property,然後再RowCommand event根據RowIndex讀出該row的PK或FK,所以第一步,必須先能在RowCommand獲得目前的RowIndex。

Introduction

.NET 1.x DataGrid
在.NET 1.x的DataGrid,若要使用LinkButton,一樣得放在TemplateColumn內,且ItemCommand event的e.Item.ItemIndex就可抓到RowIndex。

當在DataGrid點下FirstName後,會在下方的Label顯示LastName,LastName是此例的DataKey。

 如何獲得GridView內LinkButton的RowIndex? (.NET) (ASP.NET)

 1 <% @ Import Namespace="System.Data"  %>
 2 <% @ Import Namespace="System.Data.SqlClient"  %>
 3
 4 <% @ Page Language="C#"  %>
 5
 6 <! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
 7
 8 < script  runat ="server" >
 9/* 
10(C) OOMusou 2007 http://oomusou.cnblogs.com
11
12Filename    : DataGrid_DataKeyField.aspx
13Compiler    : Visual Studio 2005 / C# 2.0 / ASP.NET 2.0
14Description : Demo how to get RowIndex in DataGrid's LinkButton
15Release     : 06/26/2007 1.0
16*/

17  protected void Page_Load(object sender, EventArgs e) {
18    if (!IsPostBack) 
19      DataGrid1_DataBind();
20  }

21
22  protected void DataGrid1_DataBind() {
23    string strSQL = "SELECT TOP 10 " +
24                           "fname," +
25                           "lname " +
26                    "FROM employee";
27    SqlConnection con = new SqlConnection(@"Data Source=.\sqlexpress;Initial Catalog=pubs;Integrated Security=True");
28    SqlDataAdapter da = new SqlDataAdapter(strSQL, con);
29    DataSet ds = new DataSet();
30
31    try {
32      da.Fill(ds);
33    }

34    catch (Exception err) {
35      Response.Write(err.ToString());
36      return;
37    }

38    finally {
39      if ((con != null&& (con.State == ConnectionState.Open))
40        con.Close();
41    }

42
43    DataGrid1.DataSource = ds;
44    DataGrid1.DataKeyField = "lname";
45    DataGrid1.AutoGenerateColumns = false;
46    DataGrid1.DataBind();
47  }

48
49  protected void DataGrid1_ItemCommand(object source, DataGridCommandEventArgs e) {
50    if (e.CommandName == "Select")
51      Label1.Text = DataGrid1.DataKeys[e.Item.ItemIndex].ToString();
52  }

53
</ script >
54
55 < html  xmlns ="http://www.w3.org/1999/xhtml" >
56 < head  runat ="server" >
57    < title > Untitled Page </ title >
58 </ head >
59 < body >
60    < form  id ="form1"  runat ="server" >
61      < asp:DataGrid  ID ="DataGrid1"  runat ="server"  OnItemCommand ="DataGrid1_ItemCommand" >
62        < Columns >
63          < asp:TemplateColumn  HeaderText ="First Name" >
64            < ItemTemplate >
65              < asp:LinkButton  ID ="LinkButton1"  runat ="server"  CommandName ="Select"  Text ='<%#DataBinder.Eval(Container.DataItem,"fname")% > '>
66              </ asp:LinkButton >
67            </ ItemTemplate >
68          </ asp:TemplateColumn >
69        </ Columns >
70      </ asp:DataGrid >
71      < asp:Label  ID ="Label1"  runat ="server" ></ asp:Label >
72    </ form >
73 </ body >
74 </ html >


51行

1 protected   void  DataGrid1_ItemCommand( object  source, DataGridCommandEventArgs e)  {
2    if (e.CommandName == "Select")
3      Label1.Text = DataGrid1.DataKeys[e.Item.ItemIndex].ToString();
4}

5


只需在ItemCommand event的e.Item.ItemIndex就可以輕鬆的抓到RowIndex。

.NET 2.0 GridView
.NET 2.0就改用SqlDataSource和GridView了,LinkButtom一樣得放在TemplateField,但GridView沒有ItemCommand event,取而代之的是RowCommand event。

 1 <% @ Page Language="C#"  %>
 2
 3 <! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
 4
 5 < script  runat ="server" >
 6 /* 
 7(C) OOMusou 2007 http://oomusou.cnblogs.com
 8
 9Filename    : GridView_RowCommand_RowIndex.aspx
10Compiler    : Visual Studio 2005 / C# 2.0 / ASP.NET 2.0
11Description : Demo how to get RowIndex in GridView's LinkButton
12Release     : 06/26/2007 1.0
13*/

14  protected void Page_Load(object sender, EventArgs e) {
15    if (!IsPostBack)
16      GridView1_DataBind();
17  }

18
19  protected void GridView1_DataBind() {
20    SqlDataSource1.ConnectionString = @"Data Source=.\sqlexpress;Initial Catalog=pubs;Integrated Security=True";
21    SqlDataSource1.SelectCommand = "SELECT TOP 10 " +
22                                          "fname," +
23                                          "lname " +
24                                   "FROM employee";
25    GridView1.DataSourceID = SqlDataSource1.ID;
26    GridView1.DataKeyNames = new string[] "lname" };
27    GridView1.AutoGenerateColumns = false;
28  }

29
30  protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e) {
31    if (e.CommandName == "Select"{
32      int rowIndex = ((GridViewRow)((LinkButton)e.CommandSource).NamingContainer).RowIndex;
33      Label1.Text = GridView1.DataKeys[rowIndex].Value.ToString();
34    }

35  }

36
</ script >
37
38 < html  xmlns ="http://www.w3.org/1999/xhtml" >
39 < head  runat ="server" >
40    < title > Untitled Page </ title >
41 </ head >
42 < body >
43    < form  id ="form1"  runat ="server" >
44      < div >
45        < asp:GridView  ID ="GridView1"  runat ="server"  OnRowCommand ="GridView1_RowCommand" >
46          < Columns >
47            < asp:TemplateField  HeaderText ="First Name" >
48              < ItemTemplate >
49                < asp:LinkButton  ID ="LinkButton1"  runat ="server"  CommandName ="Select"  Text ='<%#Eval("fname")% > '> </ asp:LinkButton >
50              </ ItemTemplate >
51            </ asp:TemplateField >
52          </ Columns >
53        </ asp:GridView >
54      </ div >
55      < asp:Label  ID ="Label1"  runat ="server" ></ asp:Label >
56      < asp:SqlDataSource  ID ="SqlDataSource1"  runat ="server" ></ asp:SqlDataSource >
57    </ form >
58 </ body >
59 </ html >


最難理解的應該是32行

int  rowIndex  =  ((GridViewRow)((LinkButton)e.CommandSource).NamingContainer).RowIndex;


e.CommandSource傳的是按下去的LinkButton,不過由於傳回的是Object,就得自行轉成LinkButton,但由於我們想知道的是RowIndex,而LinkButton是包含在GridViewRow內,所以透過NamingContainer傳回目前的GridViewRow,但傳回的是Control,所以需在轉成GridViewRow後才能有RowIndex property。

Conclusion
GridView是DataGrid的繼承人,但不少寫法和DataGrid並不一樣,GridView很多地方比DataGrid更強更好用,但這個例子卻發現GridView比DataGrid麻煩些,或許我沒找到好最好的方法,若有人有更好的方式,歡迎指正,謝謝。

你可能感兴趣的:(GridView)