无法从代码后面引用文本框输入值
Unable to reference text box input value from code behind
我查看了几个答案,它们似乎都表明使用 [textboxID].Text 的格式应该允许我在后面的代码中引用输入数据,但这对我来说并不成立。我的例子如下:
/** .aspx 标记文件 **/
'''
<asp:ListView ID="ListViewWorkTypes" runat="server" InsertItemPosition="LastItem" >
<LayoutTemplate>
<table id="TypeRecords" runat="server" >
<tr id="TR1" runat="server" >
<td id="Td1" runat="server" >
<table runat="server" id="TypePlaceholder" >
<tr id="Tr2" runat="server" >
<td id="Td10" hidden="hidden" runat="server">Task Name</td>
<td id="Td20" runat="server">PhaseId</td>
<td id="Td30" runat="server">DeptId</td>
<td id="Td11" runat="server">Initial Value</td>
<td id="Td21" runat="server">Order</td>
<td id="Td23" runat="server">Math Operator</td>
<td id="Td31" runat="server">Option Value 1</td>
<td id="Td41" runat="server">Option Value 2</td>
<td id="Td51" runat="server">Option Value 3</td>
<td id="Td61" runat="server">Option Value 4</td>
<td id="Td71" runat="server">Option Value 5</td>
</tr>
<tr runat="server" id="itemPlaceholder">
</tr>
<tr runat="server">
<td runat="server" colspan="2">
<asp:DataPager ID="DataPager1" runat="server">
<Fields>
<asp:NextPreviousPagerField ButtonType="Link" />
<asp:NumericPagerField />
<asp:NextPreviousPagerField ButtonType="Link" />
</Fields>
</asp:DataPager>
</td>
</tr>
</table>
</td>
</tr>
</table>
</LayoutTemplate>
<InsertItemTemplate>
<tr id="NewWorkTaskRow">
<td id="NewTaskName">
<asp:Label runat="server" ID="TaskNameLabel" Visible="true" AssociatedControlID="TaskNameTextBox" Text="Task Name"/>
<asp:TextBox ID="TaskNameTextBox" runat="server" Visible="true" Text='<%# Bind("Name") %>' /><br />
</td>
<td id="NewPhase">
<asp:Label runat="server" ID="PhaseLabel" Text="Phase" AssociatedControlID="PhaseDropDown"/>
<asp:DropDownList ID="PhaseDropDown" runat="server" DataSourceID="SqlDataPhase" DataTextField="PhaseName" DataValueField="PhaseID" AppendDataBoundItems="true" >
<asp:ListItem Text="Choose Phase" Value="" Selected="False"></asp:ListItem>
</asp:DropDownList>
</td>
<td id="NewFunctionalArea">
<asp:Label runat="server" ID="DeptLabel" Text="Fuctional Area" AssociatedControlID="DeptDropDown" />
<asp:DropDownList ID="DeptDropDown" runat="server" DataSourceID="SqlDataDept" DataTextField="Dept" DataValueField="DeptId" AppendDataBoundItems="True">
<asp:ListItem Text="Choose Functional Area" Value="" Selected="True"></asp:ListItem>
</asp:DropDownList>
</td>
<td>
<asp:Label runat="server" ID="BaseValueLabel" AssociatedControlID="BaseValueTextBox" Text="Base Value" />
<asp:TextBox ID="BaseValueTextBox" runat="server" Text='<%# Bind("BaseValue") %>' /><br />
</td>
<td>
<asp:Label runat="server" ID="OrderLabel" AssociatedControlID="OrderTextBox" Text="Order" />
<asp:TextBox ID="OrderTextBox" runat="server" Text='<%# Bind("ordr") %>' /><br />
</td>
<td>
<asp:Label runat="server" ID="MathOperatorLabel" AssociatedControlID="MathOperatorTextBox" Text="Math Operator" />
<asp:TextBox ID="MathOperatorTextBox" runat="server" Text='<%# Bind("MathOperator") %>' /><br />
</td>
<td>
<asp:Label runat="server" ID="Opt1Label" AssociatedControlID="Opt1TextBox" Text="Option Value" />
<asp:TextBox ID="Opt1TextBox" runat="server" Text='<%# Bind("Opt1") %>' /><br />
</td>
<td>
<asp:Label runat="server" ID="Opt2Label" AssociatedControlID="Opt2TextBox" Text="Option Value" />
<asp:TextBox ID="Opt2TextBox" runat="server" Text='<%# Bind("Opt2") %>' /><br />
</td>
<td>
<asp:Label runat="server" ID="Opt3Label" AssociatedControlID="Opt3TextBox" Text="Option Value" />
<asp:TextBox ID="Opt3TextBox" runat="server" Text='<%# Bind("Opt3") %>' /><br />
</td>
<td>
<asp:Label runat="server" ID="Opt4Label" AssociatedControlID="Opt4TextBox" Text="Option Value" />
<asp:TextBox ID="Opt4TextBox" runat="server" Text='<%# Bind("Opt4") %>' /><br />
</td>
<td>
<asp:Label runat="server" ID="Opt5Label" AssociatedControlID="Opt5TextBox" Text="Option Value" />
<asp:TextBox ID="Opt5TextBox" runat="server" Text='<%# Bind("Opt5") %>' />
</td>
<td>
<asp:LinkButton ID="InsertButton" runat="server" OnClick="InsertType" Text="Insert" ></asp:LinkButton>
</td>
</tr>
</InsertItemTemplate>
'''
/** 隐藏代码 **/
'''
protected void InsertType(对象发送者,EventArgs e)
{
字符串名称 = "";
int 基值 = 0;
布尔LOE;
国际订单;
字符操作;
int Opt1 = 0;
int Opt2 = 0;
int Opt3 = 0;
int Opt4 = 0;
int Opt5 = 0;
int 类型 ID = 0;
string strtypecon = WebConfigurationManager.ConnectionStrings["DefaultEstimateConnection"].ConnectionString;
SqlConnection typeconx = new SqlConnection(strtypecon);
SqlCommand TypeCmd = new SqlCommand()
{
Connection = typeconx
};
/*** Attempted with the aforementioned TextBox ID reference ***/
Name = TaskNameTextBox.Text;
/*** Err msg: TaskNameTextBox does not exist in current context ***/
/*** Attempted with Request form ***/
Name = Request.Form["TaskNameTextBox"];
/** Checkpoint at this point of the process indicates a null value for Name **/
ListViewWorkTypes.FindControl("TaskNameTextBox").ToString();
TypeCmd.Parameters.AddWithValue("@Name", Name);
'''
这似乎与我在该网站上看到的据报道有效的其他代码没有什么不同。
好的,有几件事:
首先,如果您不使用编辑或功能中内置的网格,那么我会转储除 ItemTemplate 之外的所有模板。我发现在大多数情况下,我不需要所有额外的模板,我将它们删除(删除)。
所以,我会经常丢一个lv,用向导生成数据和布局。然后我删除页面上的数据源,然后折叠每个 edit/alternative/insert/edit 模板并删除它们。删除(删除)放置在表单上的数据源控件,然后您就可以从一堆巨大的标记变成一个简单易用的 lv.
因此,即使在您的情况下,也不清楚您是否实际使用了插入模板,或者您只是放入了一个 link 按钮并向该 link 按钮添加了一个事件。
(顺便说一句:你可以放下飞机简 asp.net 按钮 - 它们通常看起来更好)。
所以,我不知道您是否使用插入模板,但是您确实将按钮放入了插入模板,但我不知道它是否也在项目模板中。
如前所述:
您有(或可能)有 item/edit/alternating/insert 个模板。鉴于屏幕也可能有很多行?当您引用文本框时,您会从哪个模板获取哪一行、哪一行?
答案:大量世界范围内令人困惑!!!
那么,当使用 gridview、listview、repeater、formview、details view 时?
它们的工作原理几乎相同 - 从您拥有的布局被反复使用的意义上说,它们是“中继器”。结果,你当然不能使用 ay:
TaskNameTextBox.Text
现在,如前所述,您是否实际使用惰性模板一点也不清楚。如前所述,在大多数情况下,我会简单地转储除 Item 模板之外的所有模板。在大多数情况下,它是更少的代码、更少的标记、更少的维护。
好的,但是让我们解决 link 按钮点击事件和代码。
这里实际上有大约5种方法。并选择哪种方法来获得您尝试处理的行将在很大程度上取决于您尝试做什么。
可能是实现此功能的最简单方法?
您可以向按钮添加一个 CommandName 标签。此标记具有可导致 iistview 事件触发的特殊名称。但是,查看您的列表视图,您似乎没有任何连接。
因此,您可以使用 CommandName="select"
这将导致行命令触发(但行索引尚未更改!!! - 它会。但是,RowCommand 事件确实传递了该行。
但是,在上面之后,列表视图的 SelectedIndex 将触发,更重要的是索引确实发生了变化。
但是,还有另一种获取当前行的方法,让您不必学习列表视图的复杂事件模型。
您可以做的只是拾取并获取您单击的当前行(您拥有的插入 link 按钮)。当我们得到该行时,您就可以从该行中提取值。
但是,要获得这样的值,我们不能也不能不使用控件名称。你得到的是一个“object”/代表一行的东西,你可以使用 FindConrol 从中提取值。
如前所述,该控件将有大量实例,甚至还有不同的模板 - 因此您无法确定要获取的控件。
因此,对于这些“中继器”类型的控件,您不能再直接引用它们。您总是必须获取行实例,然后从该行实例中使用 FindControl out/get/grab 控件。
所以,第一部分,困难的部分和有价值的部分是获取您单击的那一行。
如前所述,您可以 have/let/allow 行索引更改事件触发,然后您可以通过 ListView2.xxxxxx.
从该事件获取当前行
但是,从那个简单的按钮放入项目模板? (如果您不使用 lv 功能进行编辑(例如插入模板),我再次强烈建议您只使用 itemtempate。
因此,在按钮单击事件中,我们可以获得所有已知和所有有价值的行。我们只需要那排东西,我们就可以自由回家了。
它是这样工作的:
protected void cmdLstSel_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
ListViewDataItem gRow = (ListViewDataItem)btn.Parent.Parent.Parent;
// ListViewDataItem gRow = (ListViewDataItem)GetParentObj(btn.Parent, typeof(ListViewDataItem));
int hID = (int)ListView1.DataKeys[gRow.DisplayIndex]["ID"];
注意数据键的使用。如果您需要并想要来自数据库的 PK 行 ID,您真的非常想设置它。这还有一个巨大的好处,就是您不必在 lv 标记中包含数据库 PK id。 (这在安全问题方面也可能是巨大的 - 您不必在标记中包含或公开数据库 PK id,因此它永远不会公开客户端 - 请记住这一点)。
好的,所以上面通过使用单击的控件的 parent 属性 获取当前行 (ListViewDataItem)。 (.parent = "
,我们再往上一个,然后再往上一个。所以,请注意我是如何使用 .Parent.Parent.Parent 的。我什至写了一个例程来为我做这件事,因为通常是由于额外的div 或其他,您可能需要再增加一些。parent 才能获得该行。
当然,对于您的情况,我们会 do/use 这样做:
LinkButton btn = (LinkButton)sender);
ListViewDataItem gRow = (ListViewDataItem)btn.Parent.Parent.Parent;
// ListViewDataItem gRow = (ListViewDataItem)GetParentObj(btn.Parent, typeof(ListViewDataItem));
int hID = (int)ListView1.DataKeys[gRow.DisplayIndex]["ID"];
但是,一旦我们有了 gRow,您就可以像这样获取给定文本框的值:
TextBox MyTaskNameTextBox;
MyTaskNameTextBox = (TextBox)gRow.FindControl("TaskNameTextbox");
// text of box now is MyTaskNameTextBox.Text
如前所述,有时您必须“猜测”要上升多少 parent 才能获得所有有价值的“行”。我经常猜测,编译和 运行,而错误消息实际上告诉我你不能将那个“td”转换为 ListViewitem,所以我放入另一个并再次编译。但是,我什至厌倦了,所以我写了这个例程来为我排行:
public Control GetParentObj(Control c, Type T)
{
if (c.Parent.GetType() == T)
return c.Parent;
else
// keep looking
return GetParentObj(c.Parent, T);
}
在我的示例代码中注意上面,我注释掉了上面的用法,但是如果您遗漏或猜测您必须冒泡多少次才能得到,您可以尝试这个例程这一排对你来说很受欢迎。
如前所述,您也可以不使用这种 .parent 方法,而是使用内置的列表视图事件,但是,我经常如前所述,转储额外模板的巨大混乱,并转储巨大的复杂lv 的事件模型,并按照我的方式正确解决这个问题(以获得所有有价值的行)。
我查看了几个答案,它们似乎都表明使用 [textboxID].Text 的格式应该允许我在后面的代码中引用输入数据,但这对我来说并不成立。我的例子如下:
/** .aspx 标记文件 **/ '''
<asp:ListView ID="ListViewWorkTypes" runat="server" InsertItemPosition="LastItem" >
<LayoutTemplate>
<table id="TypeRecords" runat="server" >
<tr id="TR1" runat="server" >
<td id="Td1" runat="server" >
<table runat="server" id="TypePlaceholder" >
<tr id="Tr2" runat="server" >
<td id="Td10" hidden="hidden" runat="server">Task Name</td>
<td id="Td20" runat="server">PhaseId</td>
<td id="Td30" runat="server">DeptId</td>
<td id="Td11" runat="server">Initial Value</td>
<td id="Td21" runat="server">Order</td>
<td id="Td23" runat="server">Math Operator</td>
<td id="Td31" runat="server">Option Value 1</td>
<td id="Td41" runat="server">Option Value 2</td>
<td id="Td51" runat="server">Option Value 3</td>
<td id="Td61" runat="server">Option Value 4</td>
<td id="Td71" runat="server">Option Value 5</td>
</tr>
<tr runat="server" id="itemPlaceholder">
</tr>
<tr runat="server">
<td runat="server" colspan="2">
<asp:DataPager ID="DataPager1" runat="server">
<Fields>
<asp:NextPreviousPagerField ButtonType="Link" />
<asp:NumericPagerField />
<asp:NextPreviousPagerField ButtonType="Link" />
</Fields>
</asp:DataPager>
</td>
</tr>
</table>
</td>
</tr>
</table>
</LayoutTemplate>
<InsertItemTemplate>
<tr id="NewWorkTaskRow">
<td id="NewTaskName">
<asp:Label runat="server" ID="TaskNameLabel" Visible="true" AssociatedControlID="TaskNameTextBox" Text="Task Name"/>
<asp:TextBox ID="TaskNameTextBox" runat="server" Visible="true" Text='<%# Bind("Name") %>' /><br />
</td>
<td id="NewPhase">
<asp:Label runat="server" ID="PhaseLabel" Text="Phase" AssociatedControlID="PhaseDropDown"/>
<asp:DropDownList ID="PhaseDropDown" runat="server" DataSourceID="SqlDataPhase" DataTextField="PhaseName" DataValueField="PhaseID" AppendDataBoundItems="true" >
<asp:ListItem Text="Choose Phase" Value="" Selected="False"></asp:ListItem>
</asp:DropDownList>
</td>
<td id="NewFunctionalArea">
<asp:Label runat="server" ID="DeptLabel" Text="Fuctional Area" AssociatedControlID="DeptDropDown" />
<asp:DropDownList ID="DeptDropDown" runat="server" DataSourceID="SqlDataDept" DataTextField="Dept" DataValueField="DeptId" AppendDataBoundItems="True">
<asp:ListItem Text="Choose Functional Area" Value="" Selected="True"></asp:ListItem>
</asp:DropDownList>
</td>
<td>
<asp:Label runat="server" ID="BaseValueLabel" AssociatedControlID="BaseValueTextBox" Text="Base Value" />
<asp:TextBox ID="BaseValueTextBox" runat="server" Text='<%# Bind("BaseValue") %>' /><br />
</td>
<td>
<asp:Label runat="server" ID="OrderLabel" AssociatedControlID="OrderTextBox" Text="Order" />
<asp:TextBox ID="OrderTextBox" runat="server" Text='<%# Bind("ordr") %>' /><br />
</td>
<td>
<asp:Label runat="server" ID="MathOperatorLabel" AssociatedControlID="MathOperatorTextBox" Text="Math Operator" />
<asp:TextBox ID="MathOperatorTextBox" runat="server" Text='<%# Bind("MathOperator") %>' /><br />
</td>
<td>
<asp:Label runat="server" ID="Opt1Label" AssociatedControlID="Opt1TextBox" Text="Option Value" />
<asp:TextBox ID="Opt1TextBox" runat="server" Text='<%# Bind("Opt1") %>' /><br />
</td>
<td>
<asp:Label runat="server" ID="Opt2Label" AssociatedControlID="Opt2TextBox" Text="Option Value" />
<asp:TextBox ID="Opt2TextBox" runat="server" Text='<%# Bind("Opt2") %>' /><br />
</td>
<td>
<asp:Label runat="server" ID="Opt3Label" AssociatedControlID="Opt3TextBox" Text="Option Value" />
<asp:TextBox ID="Opt3TextBox" runat="server" Text='<%# Bind("Opt3") %>' /><br />
</td>
<td>
<asp:Label runat="server" ID="Opt4Label" AssociatedControlID="Opt4TextBox" Text="Option Value" />
<asp:TextBox ID="Opt4TextBox" runat="server" Text='<%# Bind("Opt4") %>' /><br />
</td>
<td>
<asp:Label runat="server" ID="Opt5Label" AssociatedControlID="Opt5TextBox" Text="Option Value" />
<asp:TextBox ID="Opt5TextBox" runat="server" Text='<%# Bind("Opt5") %>' />
</td>
<td>
<asp:LinkButton ID="InsertButton" runat="server" OnClick="InsertType" Text="Insert" ></asp:LinkButton>
</td>
</tr>
</InsertItemTemplate>
'''
/** 隐藏代码 **/ ''' protected void InsertType(对象发送者,EventArgs e) { 字符串名称 = ""; int 基值 = 0; 布尔LOE; 国际订单; 字符操作; int Opt1 = 0; int Opt2 = 0; int Opt3 = 0; int Opt4 = 0; int Opt5 = 0; int 类型 ID = 0;
string strtypecon = WebConfigurationManager.ConnectionStrings["DefaultEstimateConnection"].ConnectionString;
SqlConnection typeconx = new SqlConnection(strtypecon);
SqlCommand TypeCmd = new SqlCommand()
{
Connection = typeconx
};
/*** Attempted with the aforementioned TextBox ID reference ***/
Name = TaskNameTextBox.Text;
/*** Err msg: TaskNameTextBox does not exist in current context ***/
/*** Attempted with Request form ***/
Name = Request.Form["TaskNameTextBox"];
/** Checkpoint at this point of the process indicates a null value for Name **/
ListViewWorkTypes.FindControl("TaskNameTextBox").ToString();
TypeCmd.Parameters.AddWithValue("@Name", Name);
'''
这似乎与我在该网站上看到的据报道有效的其他代码没有什么不同。
好的,有几件事:
首先,如果您不使用编辑或功能中内置的网格,那么我会转储除 ItemTemplate 之外的所有模板。我发现在大多数情况下,我不需要所有额外的模板,我将它们删除(删除)。
所以,我会经常丢一个lv,用向导生成数据和布局。然后我删除页面上的数据源,然后折叠每个 edit/alternative/insert/edit 模板并删除它们。删除(删除)放置在表单上的数据源控件,然后您就可以从一堆巨大的标记变成一个简单易用的 lv.
因此,即使在您的情况下,也不清楚您是否实际使用了插入模板,或者您只是放入了一个 link 按钮并向该 link 按钮添加了一个事件。 (顺便说一句:你可以放下飞机简 asp.net 按钮 - 它们通常看起来更好)。
所以,我不知道您是否使用插入模板,但是您确实将按钮放入了插入模板,但我不知道它是否也在项目模板中。
如前所述: 您有(或可能)有 item/edit/alternating/insert 个模板。鉴于屏幕也可能有很多行?当您引用文本框时,您会从哪个模板获取哪一行、哪一行?
答案:大量世界范围内令人困惑!!!
那么,当使用 gridview、listview、repeater、formview、details view 时?
它们的工作原理几乎相同 - 从您拥有的布局被反复使用的意义上说,它们是“中继器”。结果,你当然不能使用 ay:
TaskNameTextBox.Text
现在,如前所述,您是否实际使用惰性模板一点也不清楚。如前所述,在大多数情况下,我会简单地转储除 Item 模板之外的所有模板。在大多数情况下,它是更少的代码、更少的标记、更少的维护。
好的,但是让我们解决 link 按钮点击事件和代码。
这里实际上有大约5种方法。并选择哪种方法来获得您尝试处理的行将在很大程度上取决于您尝试做什么。
可能是实现此功能的最简单方法?
您可以向按钮添加一个 CommandName 标签。此标记具有可导致 iistview 事件触发的特殊名称。但是,查看您的列表视图,您似乎没有任何连接。
因此,您可以使用 CommandName="select"
这将导致行命令触发(但行索引尚未更改!!! - 它会。但是,RowCommand 事件确实传递了该行。
但是,在上面之后,列表视图的 SelectedIndex 将触发,更重要的是索引确实发生了变化。
但是,还有另一种获取当前行的方法,让您不必学习列表视图的复杂事件模型。
您可以做的只是拾取并获取您单击的当前行(您拥有的插入 link 按钮)。当我们得到该行时,您就可以从该行中提取值。
但是,要获得这样的值,我们不能也不能不使用控件名称。你得到的是一个“object”/代表一行的东西,你可以使用 FindConrol 从中提取值。
如前所述,该控件将有大量实例,甚至还有不同的模板 - 因此您无法确定要获取的控件。
因此,对于这些“中继器”类型的控件,您不能再直接引用它们。您总是必须获取行实例,然后从该行实例中使用 FindControl out/get/grab 控件。
所以,第一部分,困难的部分和有价值的部分是获取您单击的那一行。
如前所述,您可以 have/let/allow 行索引更改事件触发,然后您可以通过 ListView2.xxxxxx.
从该事件获取当前行但是,从那个简单的按钮放入项目模板? (如果您不使用 lv 功能进行编辑(例如插入模板),我再次强烈建议您只使用 itemtempate。
因此,在按钮单击事件中,我们可以获得所有已知和所有有价值的行。我们只需要那排东西,我们就可以自由回家了。
它是这样工作的:
protected void cmdLstSel_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
ListViewDataItem gRow = (ListViewDataItem)btn.Parent.Parent.Parent;
// ListViewDataItem gRow = (ListViewDataItem)GetParentObj(btn.Parent, typeof(ListViewDataItem));
int hID = (int)ListView1.DataKeys[gRow.DisplayIndex]["ID"];
注意数据键的使用。如果您需要并想要来自数据库的 PK 行 ID,您真的非常想设置它。这还有一个巨大的好处,就是您不必在 lv 标记中包含数据库 PK id。 (这在安全问题方面也可能是巨大的 - 您不必在标记中包含或公开数据库 PK id,因此它永远不会公开客户端 - 请记住这一点)。
好的,所以上面通过使用单击的控件的 parent 属性 获取当前行 (ListViewDataItem)。 (.parent = "
当然,对于您的情况,我们会 do/use 这样做:
LinkButton btn = (LinkButton)sender);
ListViewDataItem gRow = (ListViewDataItem)btn.Parent.Parent.Parent;
// ListViewDataItem gRow = (ListViewDataItem)GetParentObj(btn.Parent, typeof(ListViewDataItem));
int hID = (int)ListView1.DataKeys[gRow.DisplayIndex]["ID"];
但是,一旦我们有了 gRow,您就可以像这样获取给定文本框的值:
TextBox MyTaskNameTextBox;
MyTaskNameTextBox = (TextBox)gRow.FindControl("TaskNameTextbox");
// text of box now is MyTaskNameTextBox.Text
如前所述,有时您必须“猜测”要上升多少 parent 才能获得所有有价值的“行”。我经常猜测,编译和 运行,而错误消息实际上告诉我你不能将那个“td”转换为 ListViewitem,所以我放入另一个并再次编译。但是,我什至厌倦了,所以我写了这个例程来为我排行:
public Control GetParentObj(Control c, Type T)
{
if (c.Parent.GetType() == T)
return c.Parent;
else
// keep looking
return GetParentObj(c.Parent, T);
}
在我的示例代码中注意上面,我注释掉了上面的用法,但是如果您遗漏或猜测您必须冒泡多少次才能得到,您可以尝试这个例程这一排对你来说很受欢迎。
如前所述,您也可以不使用这种 .parent 方法,而是使用内置的列表视图事件,但是,我经常如前所述,转储额外模板的巨大混乱,并转储巨大的复杂lv 的事件模型,并按照我的方式正确解决这个问题(以获得所有有价值的行)。