本文轉自http://hi.baidu.com/xujie2453/blog/item/53cb9f33c1312fa35fdf0e29.html
轉載該文的目的就是讓更多的網友看到該文,以免受此問題困擾!
第一種解決方案(本人成功):在後台頁
int num = int.Parse(gv.DataKeys[dr.RowIndex].Values[0].ToString());
第二種解決方案:(摘自 http://www.cnblogs.com/Jinglecat/archive/2007/09/12/813338.html)
在 GridView/DetailsView 中如果 BoundField 的 Visible=false 時, 回傳的時候無法此列的值(GridViewRow.Cells[cellIndex].Text將為空白),網上很多朋友提出了各種各樣的解決方案,這裡整理一下,並提供樣本。
未反射 GridView 類,不曾仔細閱讀其源碼,不知內部實現對於 BoundField(普通繫結資料行),當此列 Visible=false 時,是未執行綁定計算,還是未保持 ViewState,也許這是就是傳說的GridView效能由於DataGrid的一點吧。事實上,這樣反而給粗心的開發人員帶來了“莫名其妙”的問題。DataGrid 中 BoundColumn 不存在此問題。
MSDN 對此是這樣的說明:
備忘
使用 Visible 屬性顯示或隱藏資料繫結控制項中的 DataControlField 對象。
如果 Visible 屬性為 false,則不顯示資料值並且不做到用戶端的往返行程。如果要往返不可見欄位的資料,請將欄位名添加到資料繫結控制項的 DataKeyNames 屬性。
http://msdn2.microsoft.com/zh-cn/library/system.web.ui.webcontrols.datacontrolfield.visible(VS.80).aspx
說明:BoundField 類繼承自 DataControlField 類。
事實上,實際項目中,我幾乎沒有使用隱藏列的經驗,即使在 1.x 的 DataGrid 中,為了記錄某些有用的隱藏資訊,我一般使用模板列中嵌套控制項,如label 並設定其visible=false 最佳當然是用 input type=hidden runat=server(註:1.x 中沒有 asp:hiddenfield 控制項)。
而 2.0 ,最佳的方案,當然是使用 DataKeys 來儲存,不像DataGrid.DataKey ,GridView/DetailsView.DataKeys 可以儲存多個值。
以下為範例程式碼,程式碼封裝含各種方案的“自說明”注釋,不再做過多的解釋。
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data" %>
<%--http://community.csdn.net/Expert/TopicView3.asp?id=5646507--%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack) {
LoadProductData();
}
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
// 用戶端 CSS 控制隱藏,不安全,畢竟資料還是呈現到用戶端了
e.Row.Cells[3].Style.Add(HtmlTextWriterStyle.Display, "none");
// 設定儲存格隱藏, TableCell.Visible=false, OK
e.Row.Cells[4].Visible = false;
}
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
int rowIndex = -1;
switch (e.CommandName) {
case "Select":
rowIndex = Convert.ToInt32(e.CommandArgument);
GridViewRow row = GridView1.Rows[rowIndex];
Response.Write(String.Format("<pre style='color:red'>您選擇了第 {0} 行\n當前行 ProductId={1}, CategoryId={2}(兩者均由DataKeys擷取)\n",
(row.RowIndex + 1),
GridView1.DataKeys[rowIndex].Values["ProductId"],
GridView1.DataKeys[rowIndex].Values["CategoryId"]));
for (int columnIndex=0; columnIndex< GridView1.Columns.Count; columnIndex++) {
DataControlField field = GridView1.Columns[columnIndex];
string text = null;
if (field is BoundField) {
text = row.Cells[columnIndex].Text;
}
else if (field is TemplateField) {
Label lbl = row.Cells[columnIndex].FindControl("lblProductID") as Label;
if (lbl != null) {
text = lbl.Text;
}
else {
text = row.Cells[columnIndex].Text;
}
}
Response.Write(String.Format("{0}#Type={1}#Visible={2}#CanGetText={3}#Text={4}\n",
field.HeaderText, field.GetType().Name.ToString(), field.Visible, !String.IsNullOrEmpty(text), text));
}
Response.Write("</pre>");
break;
}
}
void LoadProductData()
{
DataTable dt = CreateProductTable();
GridView1.DataSource = dt;
GridView1.DataBind();
}
#region sample data
static DataTable CreateProductTable()
{
DataTable tbl = new DataTable("Products");
tbl.Columns.Add("ProductID", typeof(int));
tbl.Columns.Add("ProductName", typeof(string));
tbl.Columns.Add("CategoryID", typeof(int));
DataRow row = tbl.NewRow();
row[0] = 1;
row[1] = "Chai";
row[2] = 1;
tbl.Rows.Add(row);
row = tbl.NewRow();
row[0] = 2;
row[1] = "Chang";
row[2] = 1;
tbl.Rows.Add(row);
row = tbl.NewRow();
row[0] = 3;
row[1] = "Aniseed Syrup";
row[2] = 2;
tbl.Rows.Add(row);
row = tbl.NewRow();
row[0] = 4;
row[1] = "Chef Anton's Cajun Seasoning";
row[2] = 2;
tbl.Rows.Add(row);
row = tbl.NewRow();
row[0] = 5;
row[1] = "Chef Anton's Gumbo Mix";
row[2] = 2;
tbl.Rows.Add(row);
row = tbl.NewRow();
row[0] = 47;
row[1] = "Zaanse koeken";
row[2] = 3;
tbl.Rows.Add(row);
row = tbl.NewRow();
row[0] = 48;
row[1] = "Chocolade";
row[2] = 3;
tbl.Rows.Add(row);
row = tbl.NewRow();
row[0] = 49;
row[1] = "Maxilaku";
row[2] = 3;
tbl.Rows.Add(row);
return tbl;
}
#endregion
protected void Button1_Click(object sender, EventArgs e)
{
LoadProductData();
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Demo6_AccessHiddenGridViewColumnValue</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="GridView1" DataKeyNames="ProductId,CategoryId" runat="server" AutoGenerateColumns="False" OnRowCommand="GridView1_RowCommand" OnRowDataBound="GridView1_RowDataBound" CellPadding="4" ForeColor="#333333">
<Columns>
<asp:BoundField DataField="ProductID" HeaderText="列0 正常狀態"/>
<asp:BoundField DataField="ProductID" HeaderText="列1 直接設定Visible=false 無法擷取值" Visible="False" />
<asp:BoundField DataField="ProductID" HeaderText="列2 width=0 用戶端依然呈現無效">
<ItemStyle Width="0px" />
</asp:BoundField>
<asp:BoundField DataField="ProductID" HeaderText="列3 用戶端 CSS 控制隱藏,不安全,畢竟資料還是呈現到用戶端了"/>
<asp:BoundField DataField="ProductID" HeaderText="列4 設定儲存格隱藏, TableCell.Visible=false, OK"/>
<asp:TemplateField HeaderText="列5 模板列直接調用 Eval " Visible="False">
<ItemTemplate>
<%# Eval("ProductID") %>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="列6 模板列嵌入 Label" Visible="False">
<ItemTemplate>
<asp:label ID="lblProductID" runat="server" Text='<%# Eval("ProductID") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="ProductName" HeaderText="列7"/>
<asp:ButtonField CommandName="Select" Text="Select" HeaderText="列8 按鈕" />
</Columns>
<FooterStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
<RowStyle BackColor="#FFFBD6" ForeColor="#333333" />
<SelectedRowStyle BackColor="#FFCC66" Font-Bold="True" ForeColor="Navy" />
<PagerStyle BackColor="#FFCC66" ForeColor="#333333" HorizontalAlign="Center" />
<HeaderStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
<AlternatingRowStyle BackColor="White" />
</asp:GridView></div>
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="重新綁定資料" />
</form>
</body>
</html>