问题
I\'m sorry, but I can\'t understand why this doesn\'t work. After compile, I receive a \"Null reference exception\". Please help.
public partial class labs_test : System.Web.UI.Page
{
protected void Button1_Click(object sender, EventArgs e)
{
if (TextBox1.Text != \"\")
{
Label Label1 = (Label)Master.FindControl(\"Label1\");
Label1.Text = \"<b>The text you entered was: \" + TextBox1.Text + \".</b>\";
}
}
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
Label Label1 = (Label)Master.FindControl(\"Label1\");
Label1.Text = \"<b>You chose <u>\" + DropDownList1.SelectedValue + \"</u> from the dropdown menu.</b>\";
}
}
and UI:
<%@ Page Language=\"C#\" MasterPageFile=\"~/MasterPage.master\" AutoEventWireup=\"true\" CodeFile=\"test.aspx.cs\" Inherits=\"labs_test\" Title=\"Untitled Page\" %>
<asp:Content ID=\"Content1\" ContentPlaceHolderID=\"head\" Runat=\"Server\">
</asp:Content>
<asp:Content ID=\"Content2\" ContentPlaceHolderID=\"ContentPlaceHolder1\" Runat=\"Server\">
Type in text and then click button to display text in a Label that is in the MasterPage.<br />
This is done using FindControl.<br />
<asp:TextBox ID=\"TextBox1\" runat=\"server\"></asp:TextBox>
<asp:Button ID=\"Button1\" runat=\"server\" OnClick=\"Button1_Click\" Text=\"Submit\" /><br />
<br />
Choose an item from the below list and it will be displayed in the Label that is
in the MasterPage.<br />
This is done using FindControl.<br />
<asp:DropDownList ID=\"DropDownList1\" runat=\"server\" AutoPostBack=\"True\" OnSelectedIndexChanged=\"DropDownList1_SelectedIndexChanged\">
<asp:ListItem>Item 1</asp:ListItem>
<asp:ListItem>Item 2</asp:ListItem>
<asp:ListItem>Item 3</asp:ListItem>
</asp:DropDownList>
<asp:Label ID=\"Label1\" runat=\"server\" Text=\"Label\"></asp:Label>
</asp:Content>
回答1:
Courtesy of Mr. Atwood himself, here's a recursive version of the method. I would also recommend testing for null on the control and I included how you can change the code to do that as well.
protected void Button1_Click(object sender, EventArgs e)
{
if (TextBox1.Text != "")
{
Label Label1 = FindControlRecursive(Page, "Label1") as Label;
if(Label1 != null)
Label1.Text = "<b>The text you entered was: " + TextBox1.Text + ".</b>";
}
}
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
Label Label1 = FindControlRecursive(Page, "Label1") as Label;
if (Label1 != null)
Label1.Text = "<b>You chose <u>" + DropDownList1.SelectedValue + "</u> from the dropdown menu.</b>";
}
private Control FindControlRecursive(Control root, string id)
{
if (root.ID == id) return root;
foreach (Control c in root.Controls)
{
Control t = FindControlRecursive(c, id);
if (t != null) return t;
}
return null;
}
回答2:
When Label1 exists on the master page:
How about telling the content page where your master page is
<%@ MasterType VirtualPath="~/MasterPages/PublicUI.Master" %>
Then making a method in the master like
public void SetMessage(string message)
{
Label1.Text = message;
}
And call it in page's code behind.
Master.SetMessage("<b>You chose <u>" + DropDownList1.SelectedValue + "</u> from the dropdown menu.</b>");
When Label1 exists on the content page
If it is simply on the same page, just call Label1.Text = someString; or if you for some reason need to use FindControl, change your Master.FindControl to FindControl
回答3:
FindControl
only searches in the immediate children (technically to the next NamingContainer), not the entire control tree. Since Label1
is not an immediate child of Master
, Master.FindControl
won't locate it. Instead, you either need to do FindControl
on the immediate parent control, or do a recursive control search:
private Control FindControlRecursive(Control ctrl, string id)
{
if(ctrl.ID == id)
{
return ctrl;
}
foreach (Control child in ctrl.Controls)
{
Control t = FindControlRecursive(child, id);
if (t != null)
{
return t;
}
}
return null;
}
(Note this is convenient as an extension method).
来源:https://stackoverflow.com/questions/1457567/c-findcontrol