Unable to reference text box input value from code behind - c#
I have reviewed several answers that all seem to indicate that using the format of [textboxID].Text should allow me to reference the input data when I am in the code behind, but this does not hold true for me. My example is as follows:
/** .aspx markup file **/
'''
<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>
'''
/** Code Behind **/
'''
protected void InsertType(object sender, EventArgs e)
{
string Name = "";
int BaseValue = 0;
bool LOE;
int ordr;
char operation;
int Opt1 = 0;
int Opt2 = 0;
int Opt3 = 0;
int Opt4 = 0;
int Opt5 = 0;
int TypeID = 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);
'''
This did not seem different from the other code I had seen on this site that had reportedly worked.
Ok,a few things:
first, if you not using the grids built in edit or features, then I would dump all templates EXCEPT for the ItemTemplate. I find in most cases, I don't need all the additional templates, and I blow them out (delete them).
So, I will often drop in a lv, use the wizard to generate the data and layout. I then delete the datasource on the page and then collapse each edit/alternative/insert/edit templates and DELETE them. blow out (delete) the datasource control placed on your form, and you go from a galactic mess of huge markup into a simple nice clear easy to work with lv.
So, even in your case, it not clear if you actually using the insert template, or that you simply drop in a linkbutton and added a event to that link button.
(BTW: you can drop in a plane jane asp.net button - they often look MUCH nicer).
So, I don't know if you using the insert template, but you do have the button dropped into your insert template, but I don't know if its ALSO in the item template.
As noted:
You have (or might) have item/edit/alternating/insert templates. And given the screen might also have many rows? The when you reference a text box, then which one and which row and from which template would you get?
Answer: massive world wide confusing!!!
So, when using a gridview, listview, repeater, formview, details view?
They all work quite much the same - they are "repeaters" in the sense that the layout you have is used over and over. As a result, you of course cannot use ay:
TaskNameTextBox.Text
Now, as noted, it not at all clear if you actually using the inert template. and as noted, in most cases, I simple dump ALL the templates except for Item template. And in most cases it is less code, less markup, less things to maintain.
Ok, however lets address the linkbutton click event and code.
There are actually about 5 approaches here. and picking which approach to get the row you trying to work on will DEPEND VERY much on what you trying to do.
Probably the most easy way to get this to work?
You can add to the button a CommandName tag. This tag has specials names that can cause the iistview events to fire. However, looking at your listview, it don't look like you have ANY of the wired up.
So, you could use CommandName="select"
This will then cause the row command to fire (but row index has NOT changed yet!!! - it will. However, RowCommand event does pass the row.
but, right after above, the SelectedIndex of the listview will fire and MORE important the index DOES change.
However, there also another way to get the current row, and save you to having to learn the COMPLEX event model of the listview.
What you can do is simply pick up and get the current row you clicked on (the insert link button you have). When we get that row you can THEN pluck out values from that row.
However, to get such values, we can't an odn't use the control names. What you do get is a "object"/thing that represents the one row, and from that you can use FindConrol to pull out the value.
As noted, there would be a gallziooon instances of that control, and even different templates- so becomes impossible as to what control you trying to get.
So, for these "repeater" types of controls, you can't reference thee control directly anymore. you ALWAYS have to get the row instance, and THEN from that row instance pluck out/get/grab the control by use of FindControl.
So, the first part, the hard part and the VALUABLE part is to get that row you clicked on.
As noted, you could have/let/allow the row index changed event fire, and from that event you can then get the current row though ListView2.xxxxxx.
Howevver, from that simple button drop into the itemtemplate? (and again I STONG recommend you only have the itemtempate if you not using the lv features to edit (such as insert template).
So, in the button click event, we can get that all knowing and all valuable row. We just need that row thing, and from that we are home free.
it works like this:
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"];
note carful the use of Datakeys. You REALLY but REALLY want to set this if you need and want the PK row ID from the database. This also has the HUGE benefit of you not having to include the database PK id in the lv markup. (this also can be huge in terms of security issues - you don't have to include or expose the database PK id in the markup and thus it is NEVER exposed client side - do keep this in mind).
Ok, so the above gets the current row (ListViewDataItem) by using the parent property of that control clicked on. (.parent = "<td">, and we go up one more, and then one more again. So, note how I used .Parent.Parent.Parent. I even wrote a routine to do this for me, since often due to a extra div or whatever, you might have to .parent up a few more to get that row.
And of course in your case, we would do/use this:
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"];
But, ONCE we have that gRow, then you can get the value of the given text box like this:
TextBox MyTaskNameTextBox;
MyTaskNameTextBox = (TextBox)gRow.FindControl("TaskNameTextbox");
// text of box now is MyTaskNameTextBox.Text
As noted, sometimes you have to "guess" how many parents to go up to get that all valued "row". I often guess, compile and run, and the error message actually tells me you can't cast that "td" to ListViewitem, so I put in another one and compile again. But, I even became tired of that, so I wrote this routine to get the row for me:
public Control GetParentObj(Control c, Type T)
{
if (c.Parent.GetType() == T)
return c.Parent;
else
// keep looking
return GetParentObj(c.Parent, T);
}
Note above in my sample code, I commented out the use of above, but you can give this routine a try if you missing or guessing as to how many parents you have to bubble up to get the row is hit and miss for you.
As noted, you could also not use this .parent approach, and use the built in listview events, but, I often as noted, DUMP the huge mess of extra templates, and dump the HUGE complex event model of the lv, and just code my way right though this issue (to get that one all valuable row).
Related
Trying to add Update panel in Item template.Getting 500 error
Pop-up is created as given in image. In given image ListView is used. In each row last dropdown depends on the second dropdown, and the second depends on the first. Entire dropdown hierarchy is kept in one Update panel for each row. If I select first dropdown I am able to change second. Dropdowns in layout template and insert template are kept in Update panel and it's working properly, but if I keep dropdowns in item template in Update panel I am getting 500 error. Tried code is as follows- <ItemTemplate> <tr> <td> <asp:TextBox ID="TextBox1" runat="server" /> </td> <td> <asp:Image ID="UserRoleImage" runat="server" /> </td> <td> --CheckBox Code-- </td> <td> --CheckBox Code-- </td> <td> --CheckBox Code-- </td> <asp:updatepanel id="Updatepanel1" runat="server" updatemode="Conditional"> <ContentTemplate> <td style="width:10%"> <asp:DropDownList ID="DropDownList1" runat="server"> </asp:DropDownList> </td> <td style="width:10%"> <asp:DropDownList ID="DropDownList2" runat="server"> </asp:DropDownList> </td> <td style="width:10%"> <asp:DropDownList ID="DropDownList3" runat="server"> </asp:DropDownList> </td> </ContentTemplate> </asp:updatepanel> <td> <asp:ImageButton ID="DeleteButton" runat="server" CommandName="Delete" /> </td> <td></td> </tr> </ItemTemplate> If I remove Update panel it works fine but on dropdown change my pop-up is getting closed. I want to update only one row of listview of pop-up. Exact same design is added in layout template and insert template.
Got the cause of crash. Since same id of Update panel was using in Item template and Alternate template. I removed Alternate template from list view and Table is rendering perfectly how I was looking for.
Listview sort code apparently interfering with item processing code
Running VWD 2010 Express on a windows 7 machine. I have a asp:listview (on a tab) that has column headers that sort the data (with no code on my part). This part works when it is by itself. But it fails when I try to then put in code to support the items in the list. So here is what I have so far: (1) I can sort the items in a listview by clicking on a header ("title" in this case) asp:ListView provides a mechanism for sorting the list by clicking on the title without using code behind. We can do this with a button like so: <asp:Button runat="server" ID="SortTitle" Text="Title" CommandName="Sort" CommandArgument="sTitle" /> No code behind. This title is in the header which is outside the item template. It works fine. I can sort lists ascending and descending to my heart's content by clicking on the associated header. This is good, but I also would like to have the program "do something" when an item in the list is clicked. (2) I can make something happen when I click on an item in the list. Fortunately, there is a mechanism for controlling what happens when an item is clicked in the list via the OnItemCommand attribute in the asp:ListView tag. <asp:ListView runat="server" ID="lvWebsites" DataSourceID="websiteSuggestionsDataSource" OnItemCommand="lv_website_click" > This works kinda so-so. It does what I want, but it reloads the page (which I don't want to do). It's a separate issue and I may open a different question on that. The main thing is that I can click on the item in the list and it executes some code behind. The real problem comes in when I use (1) and (2) together. When I do that, it ignores the CommandName="Sort" in the button tag and executes the code behind (lv_website_click) regardless of whether I click on the header (title) or an actual item in the list. It's as if the system makes no distinction between a header in a listview and an actual list item in the listview. Here's a subset of the actual code I'm using. I'm using tabs and this particular listview is on the first tab so I include that...the entire code is a fair bit longer, but I think you can get the general context with this (and most of the rest is repeats of this code). <div id='tab-container'> <div class="tab-content" style="width:1000px"> <h1 class="tab" title="Feedback on the site">Site Feedback</h1> <asp:ListView runat="server" ID="anID" DataSourceID="mydatasource" OnItemCommand="lv_website_click" > <LayoutTemplate> <table id="table1" style="background-color:White;border-collapse:collapse;" width="100%"> <tr style="background-color:White"> <td width="75%"> <asp:Button runat="server" ID="SortTitle" Text="Title" CommandName="Sort" CommandArgument="sTitle" /></td> <td> <asp:Button runat="server" ID="LinkButton1" Text="Posted" CommandName="Sort" CommandArgument="sDate" /></td> <td> <asp:Button runat="server" ID="SortDate" Text="Status" CommandName="Sort" CommandArgument="sStatus" /></td> </tr> <tr runat="server" id="itemPlaceholder"> </tr> </table> <asp:DataPager runat="server" ID="datapagerSites" PageSize="10" style="background-color:White" enableviewstate="false" PagedControlID="lvWebsites" > <Fields> <asp:TemplatePagerField> <PagerTemplate> <b> Page <asp:Label runat="server" ID="CurrentPageLabel" Text="<%# Container.TotalRowCount>0 ? (Container.StartRowIndex / Container.PageSize) + 1 : 0 %>" /> of <asp:Label runat="server" ID="TotalPagesLabel" Text="<%# Math.Ceiling ((double)Container.TotalRowCount / Container.PageSize) %>" /> ( <asp:Label runat="server" ID="TotalItemsLabel" Text="<%# Container.TotalRowCount%>" /> records) <br /> </b> </PagerTemplate> </asp:TemplatePagerField> <asp:NextPreviousPagerField ButtonType="Button" ShowFirstPageButton="true" ShowNextPageButton="false" ShowPreviousPageButton="false" /> <asp:NumericPagerField PreviousPageText="< Prev 10" NextPageText="Next 10 >" ButtonCount="10" /> <asp:NextPreviousPagerField ButtonType="Button" ShowLastPageButton="true" ShowNextPageButton="false" ShowPreviousPageButton="false" /> </Fields> </asp:DataPager> </LayoutTemplate> <ItemTemplate> <tr id="Tr1" runat="server" style="background-color:#ECE5B6;" > <td><asp:Button BackColor="#ECE5B6" CommandName="lcommand" runat="server" ID="Title" Text='<%# Eval("sTitle")%>' CommandArgument='<%# Eval("sID") %>' /></td> <td><asp:Label runat="server" ID="Label1" Text='<%# Eval("posted")%>' /></td> <td><asp:Label runat="server" ID="Status" Text='<%# Eval("sStatus")%>' /></td> </tr> </ItemTemplate> <AlternatingItemTemplate> <tr id="Tr1" runat="server" style="background-color:#FAF8CC;" > <td><asp:Button BackColor="#FAF8CC" CommandName="lcommand" runat="server" ID="Title" Text='<%# Eval("sTitle")%>' CommandArgument='<%# Eval("sID") %>' /></td> <td><asp:Label runat="server" ID="Label1" Text='<%# Eval("posted")%>' /></td> <td><asp:Label runat="server" ID="Status" Text='<%# Eval("sStatus")%>' /></td> </tr> </AlternatingItemTemplate> </asp:ListView> </div> </div> It strikes me I could maybe do both things in my own code to handle the items, but I really don't like that as I would like to use the automatic sorting behavior I get from the Listview control. I would think OnItemCommand="lv_website_click" in asp:listview tag would apply to the items and the CommandName="Sort" CommandArgument="sTitle" would apply to the headers (used for sorting) because they are outside the itemtemplate. Apparently that is not true. IS there a way to use both of these (sorting with a click on header AND code behind for items in the list) so they do not conflict with each other?
The solution is in the code-behind. protected void lv_website_click(object sender, ListViewCommandEventArgs e) { if (!e.CommandName.Equals("Sort")) { int searchID = Convert.ToInt32(e.CommandArgument.ToString()); TableAdapters.SuggestionsTableAdapter sAdapt = new TableAdapters.SuggestionsTableAdapter(); SuggestionsDataTable tbl = sAdapt.GetDataByID(searchID); tbMessage.Text = tbl.Rows[0]["message"].ToString(); lbField2.Text = tbl.Rows[0]["field2"].ToString(); lbStuff.Text = tbl.Rows[0]["stuff"].ToString(); } } The key is the "if" surrounding the body of the method. If it's not a sort event (i.e. the CommandName is not equal to "Sort" then do whatever it is you're supposed to do when you click on an item. OTHERWISE, if it is a sort, just ignore the code. I misunderstood what was happening here. I thought it was ignoring the sort and executing the other code regardless. What was happening is that if the CommandName is Sort, then it is doing the sort, but it is also executing my behind code (which is where it was having the error). That is, it was not a problem with the aspx (as I had thought), but with the c# behind.
How do I make a repeater with no datasource function until it gets one from a postback?
I have a repeater on my page which I use to display a list of search results. My issue is that the page keeps throwing me a Parser Error Message: The server tag is not well formed. error because the repeater has no datasource Repeater: <asp:Repeater runat="server" ID="rptSearchResults" > <HeaderTemplate> <h3>Search results</h3> </HeaderTemplate> <ItemTemplate> <table> <tr> <td> <asp:Label runat="server" ID="lblTitle" Text="<%# Eval("title")%>"></asp:Label> </td> </tr> <tr> <td> <asp:Label runat="server" ID="lblAdress" Text="<%# Eval("adress")%>"></asp:Label> </td> </tr> <tr> <td> <asp:Label runat="server" ID="lblZipcode" Text="<%# Eval("zipcode")%>"></asp:Label> </td> </tr> <tr> <td> <asp:Label runat="server" ID="lblCity" Text="<%# Eval("city")%>"></asp:Label> </td> </tr> <tr> <td> <asp:Label runat="server" ID="lblType" Text="<%# Eval("type")%>"></asp:Label> </td> </tr> </table> </ItemTemplate> </asp:Repeater> Above this repeater is a form where users can type in search words for primarily title, adress, zipcode, city and type. The repeater isn't supposed to fill out untill the user clicks the button which triggers the search and thus adds a datasource to the repeater. Is there a way to make it work like I want it to?
I don't think the lack of a data source is the problem - it should be fine. The error says "The server tag is not well formed." - this means there's a problem with the markup. A problem with an empty data source would cause a NullReferenceException or something similar. So, maybe the problem is your Label elements - try changing the Text attributes from this: Text="<%# Eval("type")%>" to this: Text='<%# Eval("type")%>' I think all the double quotes will confuse ASP.Net. Use a combination of single and double quotes.
What happens if you disable the repeater control by default? Does it still throw the exception? If disabling it doesn't work I'd add it dynamically as and when you need it. So that you can keep your template you can strip it out to a user control so you only have to add the user control through code and not the entire item template.
how do i response.write a block of code?
In php you can have the serverside script print back a block of formatted code by using something like print <<<HERE <code> <somemorecode></somemorecode> </code> HERE; What is the asp equivalent (C#)?? It doesn't seem to like when I don't keep all of the string on one line and i'd like to avoid having to concatenate everything as it kind of kills the purpose of preserving the formatting for readability. Here's what I have that it isn't liking. i know why its doing it, but I'd like to know how to achieve what you can in php: <% for(int i = 20; i<21;i++){ Response.Write(" <tr> <td class="style1"> <asp:DropDownList ID="docNumber" runat="server" /> </td> <td class="style1"> <asp:Label ID="Label1" runat="server" Text="This would be the title of the document." /></td> <td class="style1">#</td> <td class="style1"> <asp:DropDownList ID="supervisorName" runat="server" /> </td> </tr>"); %> This isn't for anything anyone will ever see. I'm just trying to build a throw away data entry page for myself. update: nevermind... i just realized this isn't going to work for me as it will duplicate each control id. fail. At any rate, for future reference. is there a way to do what i was trying to do as far as the code blocks go?
You might consider using an <asp:Repeater /> for this purpose: <asp:Repeater runat="server" id="repeater1"> <HeaderTemplate> <table> </HeaderTemplate> <ItemTemplate> <tr> <td class="style1"> <asp:DropDownList ID="docNumber" runat="server" /></td> <td class="style1"> <asp:Label ID="Label1" runat="server" Text="<%# Container.DataItem("DocTitle") %>"/></td> <td class="style1">#</td> <td class="style1"> <asp:DropDownList ID="supervisorName" runat="server" /></td> </tr> </ItemTemplate> <FooterTemplate> </table> </FooterTemplate> </asp:Repeater> In your code behind, you would then bind this to a list or datasource on page load (or where ever appropriate). Finally check out the ondataitembound action for custom handling of each item as it's bound. MSDN Repeater - Everything you need to know
<%= Some String Expression Here %> or <% code with Response.Write("some string"); %> the first is better if you want to print a single statement. The second is better if you have more than one expression that prints stuff (if you use loops, if/else, etc.) Keep in mind that this is considered bad practice and is frowned upon in the ASP.NET Web Forms world. You should be using controls. If you want to create some more complex layout that repeats something you should use databound controls. For tables use the GridView control, for list of options use DropDownList and for other things use layout use the ListView control (you can use it for tables too). These controls use default formatting or template for each item and are bound to a collection of items via code behind. All this is for ASP.NET Web Forms. If you are using ASP.NET MVC things are done differently.
why can't asp.net find my textbox?
I'm trying to add more fields to the CreateUserWizardStep, here is what I added: <asp:CreateUserWizardStep ID="CreateUserWizardStep1" runat="server"> <ContentTemplate> <table border="0"> <tr> <td align="right"> <asp:Label ID="NickNameLabel" runat="server" AssociatedControlID="NickName">Nick Name:</asp:Label> </td> <td> <asp:TextBox ID="NickName" runat="server"></asp:TextBox> <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ControlToValidate="NickName" ErrorMessage="Nick Name is required." ToolTip="Nick Name is required." ValidationGroup="CreateUserWizard1">*</asp:RequiredFieldValidator> </td> </tr> <%-- The default code is left unchanged, but not shown here --%> </table> </ContentTemplate> </asp:CreateUserWizardStep> Then I tried to reference the objects like this protected void NewUserWizard_CreatedUser(object sender, EventArgs e) { CreateUserWizardStep step = NewUserWizard.FindControl("CreateUserWizardStep1") as CreateUserWizardStep; TextBox nickName = step.FindControl("NickName") as TextBox; // insert additional information to the database } The problem is, I'm getting nulls for nickName. Am I using FindControl("") incorrectly?
you may want to use a recursive find control function such as here: http://stevesmithblog.com/blog/recursive-findcontrol/
FindControl only Searches the current naming container for the specified server control. i.e. It only checks the current containers direct children. You can use the Controls property to return all the children of step: ControlCollection children = step.Controls; and enumerate over this looking for your text box.
I don't know the control myself, but doesn't CreateUserWizardStep1.NickNameLabel work?