Reputation: 59
I'm really struggling with this. The problem is only with the content pages.
I am trying to access a Text Box value from one content page ("Page1.aspx") in another content page ("Page2.aspx"). I'm not sure whether it is relevant that they are the children of nested master pages, but I thought I'd throw it in.
Page1.aspx is a basic form with text boxes and a submit button. The text box in Page1.aspx is called "tbFirst". The submit button has the following code:
<asp:Button ID="Button1" runat="server" Text="New Member Form" PostBackUrl="Page2.aspx"/>
Page2.aspx is a new form which should be populated with a textbox value from the previous page.
The second line show <%@ PreviousPageType VirtualPath="~/Page1.aspx" %>
For testing purposes I am using a label ("lblResult") to display my results.
Codebehind looks like this:
if (PreviousPage != null)
{
TextBox SourceTextBox =
(TextBox)PreviousPage.FindControl("tbFirst");
if (SourceTextBox != null)
{
lblResult.Text = SourceTextBox.Text;
}
else
{
lblResult.Text = "No text found";
}
}
else
{
lblResult.Text = "No Control found";
}
}
}
The problem is that the label text in Page2.aspx says "No text found".
I think that's all the relevant info. Anyone got any ideas? I've spent the whole afternoon trawling the forums and nothing I've tried works.
Upvotes: 2
Views: 3562
Reputation: 460288
I'm not sure whether it is relevant that they are the children of nested master pages, but I thought I'd throw it in.
The MasterPage
is exactly what's causing this issue. You cannot find a control on a page with MasterPage by using Page.FindControl("ControlID")
, because the Page is not the NamingContainer of the TextBox but the ContentPlaceholder
. The only control in the page's ControlCollection
with MasterPage is the MasterPage itself.
Reason: I've recently answered a question that describes this behaviour.
Here are some ways how you can access the TextBox from Page2:
You might have luck with following approach(the most direct FindControl way)
:
Page.Master.FindControl("ContentPlaceHolder1").FindControl("tbFirst");
Another, better approach would be to provide a public property in Page1
that returns tbFirst.Text
. Then you could access it in the following way from Page2
:
if (PreviousPage != null && PreviousPage is Page1){
lblResult.Text = ((Page1)PreviousPage).TbFirstText;
}
You could also add the Text
as URL-Parameter, so that it's not required that Page2's
PreviousPage
is Page1
.
Last but not least. If you use Server.Transer with preserveForm
set to tue, you would be able to retrieve the value of the original page TextBox
control by referencing Request.Form("TbFirst")
.
Note: I don't recommend a recursive FindControl approach(starting from MasterPage
), because it would also hardwire both pages and would be
Upvotes: 3
Reputation: 11955
Try using FindControlRecursive(this.Master, "tbFirst")
from this class.
(Put this class in App_Code)
using System.Web;
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
/// <summary>
/// Summary description for ControlHelper
/// </summary>
public static class ControlHelper
{
// Example: HtmlForm form = ControlHelper.FindControlRecursive(this.Master, "form1") as HtmlForm;
/// <summary>
/// Finds a Control recursively. Note finds the first match and exits
/// </summary>
/// <param name="ContainerCtl"></param>
/// <param name="IdToFind"></param>
/// <returns></returns>
public static Control FindControlRecursive(this Control Root, string Id)
{
if (Root.ID == Id)
return Root;
foreach (Control Ctl in Root.Controls)
{
Control FoundCtl = FindControlRecursive(Ctl, Id);
if (FoundCtl != null)
return FoundCtl;
}
return null;
}
//ModifyControl<TextBox>(this, tb => tb.Text = "test");
public static void ModifyControl<T>(this Control root, Action<T> action) where T : Control
{
if (root is T)
action((T)root);
foreach (Control control in root.Controls)
ModifyControl<T>(control, action);
}
}
Upvotes: 0