如何在后面的代码中更新隐藏的字段
在阿尔伯特(Albert)关于gridview
的出色答案之后,我很清楚,这个问题的原始措辞导致了混乱。 gridview
只是控件上的一个元素 - 对于所有范围和目的而言,它可能只是一个在数据标准中存储一个值的按钮。
为了澄清目的,我将发布页面和内部控制的完整标记,以及当前形式的完整代码。
这是ascx
标记:
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="MyClasses.ascx.cs" Inherits="Utilities_CourseChange_MyClasses" %>
<style>
.hiddenCol {
display: none !important;
}
</style>
<asp:Panel ID="Panel1" runat="server">
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<div style="height: 8px;"></div>
<asp:HiddenField ID="hfTEST" runat="server" />
<span style="width: 100%; display: inline-block; text-align: center; font-size: 8pt;">Tutor Groups</span>
<asp:GridView ID="gvTutorGroups" runat="server" AutoGenerateColumns="False" DataSourceID="sqlTutorGroups" DataKeyNames="TTGP_Group_Code" AllowPaging="True" PageSize="8" EmptyDataText="You have no tutor groups to display." Style="margin: 0 auto; width: 870px;" OnRowDataBound="gvTutorGroups_RowDataBound" OnSelectedIndexChanged="gvTutorGroups_SelectedIndexChanged">
<Columns>
<asp:TemplateField ItemStyle-CssClass="hiddenCol" HeaderStyle-CssClass="hiddenCol">
<ItemTemplate>
<asp:HiddenField runat="server" ID="hfTTGPISN" Value='<%# Eval("TTGP_ISN") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="TTGP_Group_Code" HeaderText="TG Code" />
<asp:BoundField DataField="PRPH_Title" HeaderText="Name" />
<asp:BoundField DataField="TTGP_Start_Date" HeaderText="Start Date" DataFormatString="{0:d}" />
<asp:BoundField DataField="TTGP_End_Date" HeaderText="End Date" DataFormatString="{0:d}" />
</Columns>
</asp:GridView>
<asp:LinkButton ID="lnkDummy" runat="server"></asp:LinkButton>
<asp:SqlDataSource ID="sqlTutorGroups" runat="server" ConnectionString="My connection string" SelectCommand="My silly little database query - has two parameters, and spit out the values for the grid">
<SelectParameters>
<asp:Parameter DefaultValue="<%$ AppSettings:CurrentAcademicYear %>" Type="String" Name="YearRef" />
</SelectParameters>
</asp:SqlDataSource>
<div style="height: 8px;"></div>
</ContentTemplate>
</asp:UpdatePanel>
</asp:Panel>
现在我可以将gridview
从updatepanel
中拉出,但我不确定它会带来什么区别。
在“ ASCX”背后的代码中,我有一个:
using System;
using System.Data;
using System.Web;
using System.Web.UI.WebControls;
public partial class Utilities_CourseChange_MyClasses : System.Web.UI.UserControl
{
protected void gvTutorGroups_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//Change the mouse cursor to Hand symbol to show the user the cell is selectable
e.Row.Attributes["onmouseover"] = "this.style.textDecoration='underline';this.style.cursor='Pointer'";
e.Row.Attributes["onmouseout"] = "this.style.textDecoration='none';";
e.Row.Attributes["onclick"] = Page.ClientScript.GetPostBackClientHyperlink(gvTutorGroups, "Select$" + e.Row.RowIndex);
}
}
protected void gvTutorGroups_SelectedIndexChanged(object sender, EventArgs e)
{
foreach (GridViewRow row in gvTutorGroups.Rows)
{
if (row.RowIndex == gvTutorGroups.SelectedIndex)
{
row.CssClass = "rowSelected";
DataRowView dataItem = (DataRowView)row.DataItem; //An unreferenced remnant of a previous attempt that I forgot to delete
HiddenField hfTGIsn = (HiddenField)this.Parent.FindControl("hfTGisn"); //Hidden field on the parent page, NOT the ASCX
hfTGIsn.Value = ((HiddenField)row.FindControl("hfTTGPISN")).Value;
hfTEST.Value = ((HiddenField)row.FindControl("hfTTGPISN")).Value; // I've put this in to test whether or not it's an issue with everything being reset, or just passing it up to the parent page that's playing up
}
else
{
row.CssClass = "";
}
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
var loginName = HttpContext.Current.User.Identity.Name.ToLowerInvariant().Trim().Replace("domainName", "");
sqlTutorGroups.SelectParameters.Add("UserName", loginName);
}
}
}
现在,我知道这不一定是最好的方法 - 但是,这是一个旧系统,我们在编写新兴系统时要维护的是,最终更换它。因此,我不一定要寻找最佳的方法,只是一种可以正常工作的方法 - 我已经从系统的其他部分提起了一半的代码将其拉入集中式页面。
现在,父aspx
当前看起来像这样:
<%@ Page Title="Course Change Tool" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="ProgCoachChangeRequester.aspx.cs" Inherits="Utilities_CourseChange_ProgCoachChangeRequester" EnableEventValidation="false" %>
<%@ Register Src="~/Utilities/CourseChange/MyClasses.ascx" TagName="Groups" TagPrefix="uc1" %>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="Server">
<asp:HiddenField ID="hfTGisn" runat="server" />
<div class="content">
<uc1:Groups ID="MyGroups" runat="server"></uc1:Groups>
</div>
<div runat="server" id="testDiv"></div>
</asp:Content>
背后的代码很简单:
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class Utilities_CourseChange_ProgCoachChangeRequester : Page
{
protected void Page_Load(object sender, EventArgs e)
{
hfTGisn.Value = ((HiddenField)MyGroups.FindControl("hfTEST")).Value;
testDiv.InnerText = hfTGisn.Value.ToString();
}
}
现在,ascx
中的所有内容似乎都很好地工作 - 我的问题是,我的问题是踏入代码时,我可以看到我的期望的值正在更新;但是Chrome上的Dev Tools窗口中的最终产品表明,虽然hftest
(我在ASCX中放置的隐藏字段以测试机制)值已更新,但hftgisn 不是。如此屏幕截图所示:
我真的不在乎我如何将价值获取到父aspx(此时,对于它给我的所有麻烦,我是一半辩论只需将其全部从ASCX中拉出,然后将其全部推入ASPX) - 我只需要该值就可以开始编写页面的其余部分。
那么,从ASCX内部到父页面上汲取价值的最简单方法是什么?
进行进一步尝试更新:
按照另一个答案的建议,我尝试使用viewState
,将aspx
页面背后的代码更改为:
protected void Page_Load(object sender, EventArgs e)
{
hfTGisn.Value = HfTGisn;
testDiv.InnerText = HfTGisn;
}
public string HfTGisn
{
get
{
return (string)ViewState["hfTGisn"];
}
set
{
ViewState["hfTGisn"] = value;
}
}
并更改gvtutorgroups_selectedIndexChanged << /代码>:
protected void gvTutorGroups_SelectedIndexChanged(object sender, EventArgs e)
{
foreach (GridViewRow row in gvTutorGroups.Rows)
{
if (row.RowIndex == gvTutorGroups.SelectedIndex)
{
row.CssClass = "rowSelected";
HiddenField hfTGIsn = (HiddenField)this.Parent.FindControl("hfTGisn");
hfTGIsn.Value = ((HiddenField)row.FindControl("hfTTGPISN")).Value;
hfTEST.Value = ((HiddenField)row.FindControl("hfTTGPISN")).Value;
ViewState["hfTGisn"] = hfTGIsn.Value;
}
else
{
row.CssClass = "";
}
}
}
但是,似乎ViewState
未在page_load
中填充
After Albert's brilliant answer about GridView
s it became clear to me that the original wording of the question led to confusion. The GridView
is just an element on the control - for all extents and purposes it could just be a button that has a value stored in a datatag.
For clarification purposes, I will post the full markup for the page and inner control, as well as the full code in it's current form.
Here's the ascx
markup:
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="MyClasses.ascx.cs" Inherits="Utilities_CourseChange_MyClasses" %>
<style>
.hiddenCol {
display: none !important;
}
</style>
<asp:Panel ID="Panel1" runat="server">
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<div style="height: 8px;"></div>
<asp:HiddenField ID="hfTEST" runat="server" />
<span style="width: 100%; display: inline-block; text-align: center; font-size: 8pt;">Tutor Groups</span>
<asp:GridView ID="gvTutorGroups" runat="server" AutoGenerateColumns="False" DataSourceID="sqlTutorGroups" DataKeyNames="TTGP_Group_Code" AllowPaging="True" PageSize="8" EmptyDataText="You have no tutor groups to display." Style="margin: 0 auto; width: 870px;" OnRowDataBound="gvTutorGroups_RowDataBound" OnSelectedIndexChanged="gvTutorGroups_SelectedIndexChanged">
<Columns>
<asp:TemplateField ItemStyle-CssClass="hiddenCol" HeaderStyle-CssClass="hiddenCol">
<ItemTemplate>
<asp:HiddenField runat="server" ID="hfTTGPISN" Value='<%# Eval("TTGP_ISN") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="TTGP_Group_Code" HeaderText="TG Code" />
<asp:BoundField DataField="PRPH_Title" HeaderText="Name" />
<asp:BoundField DataField="TTGP_Start_Date" HeaderText="Start Date" DataFormatString="{0:d}" />
<asp:BoundField DataField="TTGP_End_Date" HeaderText="End Date" DataFormatString="{0:d}" />
</Columns>
</asp:GridView>
<asp:LinkButton ID="lnkDummy" runat="server"></asp:LinkButton>
<asp:SqlDataSource ID="sqlTutorGroups" runat="server" ConnectionString="My connection string" SelectCommand="My silly little database query - has two parameters, and spit out the values for the grid">
<SelectParameters>
<asp:Parameter DefaultValue="<%$ AppSettings:CurrentAcademicYear %>" Type="String" Name="YearRef" />
</SelectParameters>
</asp:SqlDataSource>
<div style="height: 8px;"></div>
</ContentTemplate>
</asp:UpdatePanel>
</asp:Panel>
Now I could pull the GridView
out of the UpdatePanel
but I'm not sure what difference it would make.
In the code behind for the `ASCX', I have this:
using System;
using System.Data;
using System.Web;
using System.Web.UI.WebControls;
public partial class Utilities_CourseChange_MyClasses : System.Web.UI.UserControl
{
protected void gvTutorGroups_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//Change the mouse cursor to Hand symbol to show the user the cell is selectable
e.Row.Attributes["onmouseover"] = "this.style.textDecoration='underline';this.style.cursor='Pointer'";
e.Row.Attributes["onmouseout"] = "this.style.textDecoration='none';";
e.Row.Attributes["onclick"] = Page.ClientScript.GetPostBackClientHyperlink(gvTutorGroups, "Selectquot; + e.Row.RowIndex);
}
}
protected void gvTutorGroups_SelectedIndexChanged(object sender, EventArgs e)
{
foreach (GridViewRow row in gvTutorGroups.Rows)
{
if (row.RowIndex == gvTutorGroups.SelectedIndex)
{
row.CssClass = "rowSelected";
DataRowView dataItem = (DataRowView)row.DataItem; //An unreferenced remnant of a previous attempt that I forgot to delete
HiddenField hfTGIsn = (HiddenField)this.Parent.FindControl("hfTGisn"); //Hidden field on the parent page, NOT the ASCX
hfTGIsn.Value = ((HiddenField)row.FindControl("hfTTGPISN")).Value;
hfTEST.Value = ((HiddenField)row.FindControl("hfTTGPISN")).Value; // I've put this in to test whether or not it's an issue with everything being reset, or just passing it up to the parent page that's playing up
}
else
{
row.CssClass = "";
}
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
var loginName = HttpContext.Current.User.Identity.Name.ToLowerInvariant().Trim().Replace("domainName", "");
sqlTutorGroups.SelectParameters.Add("UserName", loginName);
}
}
}
Now, I'm aware this isn't necessarily the best way of doing it - but it's a legacy system that we're maintaining while writing a new system in Blazor to eventually replace it. So I'm not necessarily looking for the best way of doing it, just a way that will work - I've lifted half of this code from other parts of the system to pull it into a centralised page.
Now the parent ASPX
currently looks like this:
<%@ Page Title="Course Change Tool" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="ProgCoachChangeRequester.aspx.cs" Inherits="Utilities_CourseChange_ProgCoachChangeRequester" EnableEventValidation="false" %>
<%@ Register Src="~/Utilities/CourseChange/MyClasses.ascx" TagName="Groups" TagPrefix="uc1" %>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="Server">
<asp:HiddenField ID="hfTGisn" runat="server" />
<div class="content">
<uc1:Groups ID="MyGroups" runat="server"></uc1:Groups>
</div>
<div runat="server" id="testDiv"></div>
</asp:Content>
With the code behind literally being as simple as:
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class Utilities_CourseChange_ProgCoachChangeRequester : Page
{
protected void Page_Load(object sender, EventArgs e)
{
hfTGisn.Value = ((HiddenField)MyGroups.FindControl("hfTEST")).Value;
testDiv.InnerText = hfTGisn.Value.ToString();
}
}
Now, everything in the ASCX
seems to be working perfectly - my issue is that, when stepping through the code I can see the values being updated as I'd expect; but the end product in the dev tools window on Chrome indicates that, while the hfTEST
(that hidden field I'd put in the ascx to test the mechanism) value is getting updated, the value for hfTGisn
is not. As is evident in this screencap:
I don't really care too much how I get the value into the parent ASPX (at this point, for all the hassle it's giving me, I'm half debating just pulling it all out of the ASCX and just shoving it all into the ASPX) - I just need the value so that I can start writing the rest of the page.
So, what's the easiest way to pluck the value from within the ascx, to the parent page?
Update with further attempt:
Following the suggestion of another answer, I attempted to utilise the ViewState
, changing the code behind the ASPX
page to:
protected void Page_Load(object sender, EventArgs e)
{
hfTGisn.Value = HfTGisn;
testDiv.InnerText = HfTGisn;
}
public string HfTGisn
{
get
{
return (string)ViewState["hfTGisn"];
}
set
{
ViewState["hfTGisn"] = value;
}
}
And changing the gvTutorGroups_SelectedIndexChanged
method to:
protected void gvTutorGroups_SelectedIndexChanged(object sender, EventArgs e)
{
foreach (GridViewRow row in gvTutorGroups.Rows)
{
if (row.RowIndex == gvTutorGroups.SelectedIndex)
{
row.CssClass = "rowSelected";
HiddenField hfTGIsn = (HiddenField)this.Parent.FindControl("hfTGisn");
hfTGIsn.Value = ((HiddenField)row.FindControl("hfTTGPISN")).Value;
hfTEST.Value = ((HiddenField)row.FindControl("hfTTGPISN")).Value;
ViewState["hfTGisn"] = hfTGIsn.Value;
}
else
{
row.CssClass = "";
}
}
}
But, seemingly the ViewState
isn't populated in Page_Load
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
对于多个发回,您可以使用
ViewState
。由于Web应用程序是无状态的,因此在请求整个页面及其控件之后,再次创建了上一页,并且丢失了控件及其值。
ViewState
有助于管理页面状态。您可以尝试这样的事情:
在添加
HftGisn
后面的代码中,为progcoachangerequester
部分类属性。在
page_load
中添加gvtutorgroups_selectedIndexchanged
事件处理程序addas poul bak 已经指出,您已经可以访问
ascx
ascx < /code>控件
hftgisn
,我认为所有其他控件都相同,包括hfttgpisn
。从
gridview
中选择id
id 保存在hftgisn
属性中(基本上存储在viewState
)中,因此不是丢失的。hftgisn
然后将属性的值存储为hftgisn
隐藏字段的值,均在gvtutorgroups_selectedIndexChanged
event Handler和page_load load
中。您已经说过,
hftgisn
隐藏字段的值在page_load
中读取,因此我想您可以直接从属性读取它。更重要的是,您甚至不需要隐藏的字段,如果其唯一目的是从gridview
存储所选的id
。这是快速修复的,但是我认为找到第二个后备来自哪里更重要。在执行
gvtutorgroups_selectedIndexchanged
之后,我没有其他想法。edit :也许Simples解决方案是在
gridview
inpage_load
中读取选定的价值。GridView
和其他控件默认情况下将其值存储在ViewState
中。编辑2 :
谢谢您的澄清。
我没有设法复制这个问题,我成功地将价值从控制到父母的隐藏字段传递。
但是,我认为有一种方法可以解决您所面临的问题,尽管解决方案远非良好,但它有效(至少我希望它会)。
本答案中提出的所有其他更改都应被拒绝。
我仍然怀疑隐藏字段的价值是在其他请求后重置的。而不是
ViewState
让我们使用session
。ViewState
在页面及其控件之间无法共享。会话
可以在单个会话期间通过整个应用程序共享。在事件中,处理程序商店
iD
gridview
insession
in nime sund in session 是唯一的(您可以将名称存储在某个地方,可以从可以轻松地从代码的任何部分)。不要忘记将值存储到隐藏字段中:在
page_load
从会话到隐藏字段,不仅应在回发的情况下执行:In the case of multiple postbacks you could use
ViewState
.Because web application is stateless, after a request the entire page and its controls are created again and the previous page, controls and their values are lost.
ViewState
helps managing the page's state.You might try something like this:
In code behind add
HfTGisn
asProgCoachChangeRequester
partial class property.In
Page_Load
addIn
gvTutorGroups_SelectedIndexChanged
event handler addAs Poul Bak stated, you can already access
ascx
controlhfTGisn
and I think it is the same for all other controls, includinghfTTGPISN
.This way selected
ID
fromGridView
is saved inHfTGisn
property (essentially stored inViewState
) and therefor it is not lost.HfTGisn
property's value is then stored as value ofhfTGisn
hidden field, both ingvTutorGroups_SelectedIndexChanged
event handler and inPage_Load
.You've said that
hfTGisn
hidden field's value is read inPage_Load
, so I suppose you could read it directly from the property. Even more, you maybe don't even need the hidden field, if its only purpose is to store the selectedID
fromGridView
.This is quick fix, but I think it is more important to find where is the second postback coming from. I have no other idea than debugging every step after
gvTutorGroups_SelectedIndexChanged
is executed.Edit: Maybe the simples solution is to read selected
ID
fromGridView
inPage_Load
, and store it as hidden field's value.GridView
and other controls store their value inViewState
by default.Edit 2:
Thank you for clarification.
I didn't manage to reproduce the issue, I've successfully passed value from control to parent's hidden field.
However, I think there is a way to fix the problem you are facing, although the solution is far from good, but it works (at least I hope it will).
All other changes proposed in this answer should be rejected.
I still suspect hidden field's value is reset after some additional request. Instead of
ViewState
let's useSession
.ViewState
cannot be shared between page and its controls.Session
can be shared through entire application, during single session.In event handler store
ID
ofGridView
inSession
and name it to be unique (you could store the name somewhere where you can access it easily from any part of code). Don't forget to store the value to hidden field, too:In
Page_Load
of the parent page store value from session to hidden field and it should be always executed, not only in case of postback:好的,这里有很多问题。我们将尝试解释一些:
首先,您不会显示网格视图标记。不是世界的尽头,但是它确实会增加此页面的完整性 - 虽然简单,但介绍GridView确实会引入一定数量的学习曲线。
接下来:
您没有提及或注意如何触发所选索引。 Perahps您打开此行的“选择”按钮? (再次:这里有一个很大的细节)。
好的,无论如何,我们正在触发所选索引事件。
因此,考虑到这一点,您可以使用代码获得当前的网格视图行:
因此,如果这是模板列,则使用查找控件。
因此,如果这是一个绑定字段,则必须使用.cells []数组。
现在,我们经常要单击一行,然后通过数据库主密钥ID来传递,但是我们肯定不想在GV中显示该键。
解决此问题的最佳方法是使用Datakeys功能。它很简单,简单,而且很安全,也很安全,因为我们不必隐藏,甚至在网格标记中包含该PK行。
那么,解决这个问题的方法吗?通常,我只是将Jane常规ASP.NET按钮放入标记中。
这样说:(
对于演示,我将酒店名称作为标签 - 模板列,因此我们有一个“混合”数据绑定字段,模板(标签),并且很好地衡量了飞机Jane ASP.NET按钮因此
,我们有这样的
代码是:
我们现在有:
所以,现在我们要做的就是为简单的平面jane jane按钮单击事件添加代码存根
。控件(和按钮)在GV之外,您只需单击它们,消除属性表(甚至双击设计视图中的按钮,然后跳到后面的代码。
但是,对于内部的控件,您不能这样做 ,并让Visual Studio接线该事件。
在GV中,我们必须翻转标记 创建点击事件。
选择
可以 。
代码:
输出:
如前所述,我们无法在此处使用Dataitem属性(以获取完整的基础数据行)。
Dataitem属性仅在数据约束事件中有效。
但是,在大多数情况下,这都不重要。
由于我们具有网格视图行,因此我们可以获取显示的任何值。
在我的示例中,我们可以在此处获取隐藏的数据库行PK ID(“ ID”)。再一次,非常好,因为我们因此不必隐藏,尝试保存甚至包括并显示数据库PK ID,但是服务器端自动管理它 - 无需保存或将该值移开某个位置,由于一旦我们拥有GV行,我们就会获得行索引,并且使用行索引,我们将基于该行索引获得Datakeys值。
因此,现在,我们可以说跳到另一个页面,甚至可以将GV隐藏在“ DIV”中,然后显示中继器项目,数据视图或其他内容。而且我们可能应该基于该PK ID来做到这一点。
因此,在同一页面上说,我放入了数据中继器。
(但隐藏),说:
然后在上面的GV按钮中,我们可以添加此代码:
现在,当我单击一行时,我得到了:
或如前所述,我们可以跳跃,到另一页。
因此,一旦我们有了网格行,就可以获得我们想要的很多东西 - 即使是对所有行数据的重新询问以显示列等。在网格中不需要。
因此,总而言之:
您可以放入平面jane按钮 - 只需使用平面jane点击事件即可。您可以使用“ NamingContainer”来获取网格行。实际上,可能会更好,更清晰,然后使用内置的选定索引事件。
在databind()发生后,您无法使用Dataitem属性,它将始终为null。您可以在绑定期间(例如行数据绑定事件)中的事件中和期间使用Dataitem。
您不需要显示,隐藏,藏起来,单击行以获取标识该行的数据库PK ID,这就是GV的Datakeys设置。
编辑:牢记上述?
好的,现在我们有索引了吗?
我们可以自由地“推动”将其索引价值纳入隐藏控件。
对于GV之外的控件,我们只能在代码中直接引用它们,并且不需要某种查找控制。
因此,我们会这样做:
Ok, lots of issues here. And we will try explain a few:
First up, you don't show the grid view markup. Not the end of the world, but it certainly does incrase the completixty of this page - while simple, introduction of a GridView DOES introduce a signfiicnt amount of learning curve.
Next up:
You don't mention or note how you are triggering the selected index. Perahps you turned on the "select" button for this row?? (again: a BIG detail here).
Ok, so regardless, we ARE triggering the selected index event.
So, with that in mind, you can get the current grid view row like this with your code:
So, if this is a templated column, you use find control.
So, if this is a bound field, then you MUST use .cells[] array.
Now, VERY often, we want to click on a row, and pass say the database primary key id, but we for sure do NOT want to display that key in the GV.
the best way to deal with that is to use the DataKeys feature. It is simple, easy, and ALSO is nice and secure since we don't have to hide, or even include that PK row in the grid markup.
So, the way to approach this? Often I just drop in a plane jane regular asp.net button right into the markup.
Say, like this:
(and for demo, I put Hotel Name as a label - templated column, so we have a "mix" of data bound fields, a templated (label), and for good measure a plane jane asp.net button.
So, we have this:
Code to load is this:
And we now have this:
so, now all we have to do is add the code stub for the simple plane jane button click event.
While controls (and buttons) outside of the GV, you can just click on them, disaplay property sheet (or even double click on the button in design view, and you jumped to code behind.
However, you can't do that for controls inside of the GV, so, we have to flip into markup, and get Visual Studio to wire up that event.
You simple for the button type in onclick=, when you hit "=", the intel-sense pops up, and you THEN can choose to create the click event.
You see this:
So, choose create event - don't seem like happens, but you now have this:
And flip to code behind, and we can write this code:
output:
As noted, we can NOT use the DataItem property here (to get the full underlying data row).
DataItem property is ONLY valid duriing the data bound event.
However, for the most part, it should not matter.
Since we have the grid view row, we can get ANY value displayed.
We can get the hidden database row PK id here ("id") in my example. Again, VERY nice, since we thus don't have to hide, try to save, or even include and display the database PK id, but it is managed automatic by the server side - no need to save or shove that value away some place, since once we have the GV row, then we get the row index, and with row index, we get datakeys value based on that row index.
So, now, we can say jump to another page, or even hide the GV in a "div" and then show a Repeater item, or Data View or whatever. And we probably should do that based on that PK id.
So, say on the same page, I dropped in a data repeater.
(but hidden), say this:
Then in my gV button click above, we could add this code:
Now, when I click on a row, I get this:
Or as noted, we could jump to another page.
So, once we have the grid row, from that we can get quite much anything we want - even a re-query of ALL of the row data to display columns etc. not necessary in the grid.
So, in summary:
You can drop in a plane jane button - just use a plane jane click event. You can use "namingcontainer" to get the grid row. Really, probablly nicer and clearner then using the built in selected index event.
You can NOT use DataItem property AFTER the databind() occures it will ALWAYS be null. You CAN use DataItem in and during events during binding (such as row data bound event).
You do NOT need to show, hide, tuck away the row click to get the database PK id that identifies the row - that is what the datakeys setting of GV is for.
Edit: with above in mind?
Ok, so now that we have the index?
We are free to "shove" that index value into the hidden control.
For controls outside of the GV, we simply can reference them directly in our code, and no need for some kind of find control exists.
So, we would do this: