2009-09-22 8 views
8

Je suis désolé, mais je ne comprends pas pourquoi cela ne fonctionne pas. Après la compilation, je reçois une "exception de référence nulle". S'il vous plaît aider.C#, FindControl

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>"; 
    } 
} 

et l'interface utilisateur:

<%@ 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> 
+0

Où obtenez-vous l'exception de référence nulle? – Joren

+0

Label1.Text = "" Vous avez choisi "+ DropDownList1.SelectedValue +" dans le menu déroulant "; – AlexC

+0

Copie possible http://stackoverflow.com/questions/799655/asp-net-findcontrol-is-not-working-how-come –

Répondre

22

Avec la permission de Mr. Atwood himself, voici une version récursive de la méthode. Je recommande également de tester null sur le contrôle et j'ai inclus comment vous pouvez changer le code pour le faire aussi.

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; 
} 
+0

Merci beaucoup !!!!!!! – AlexC

+2

Bon lorsque FindControl doit être utilisé, mais dans l'exemple de cette question, FindControl est trop puissant. – CRice

2

FindControl recherche uniquement dans les enfants immédiats (techniquement à la prochaine NamingContainer), et non pas l'arbre de contrôle entier. Depuis Label1 n'est pas un enfant immédiat de Master, Master.FindControl ne le retrouvera pas. Au lieu de cela, vous devez soit faire FindControl sur le contrôle parent immédiat, ou faire une recherche de contrôle récursif:

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; 
} 

(Notez que cette pratique comme extension method).

3

Lorsque Label1 existe sur la page principale:

Que diriez-vous dire la page de contenu où votre page principale est

<%@ MasterType VirtualPath="~/MasterPages/PublicUI.Master" %> 

Ensuite, faire une méthode dans le maître comme

public void SetMessage(string message) 
{ 
    Label1.Text = message; 
} 

Et appelez-le dans le code de la page derrière.

Master.SetMessage("<b>You chose <u>" + DropDownList1.SelectedValue + "</u> from the dropdown menu.</b>"); 

Lorsque Label1 existe sur la page de contenu

S'il est tout simplement sur la même page, il suffit d'appeler Label1.Text = someString; ou si, pour une raison quelconque, vous devez utiliser FindControl, changez votre Master.FindControl en FindControl

+0

+1, supprimé ma réponse. C'est un moyen beaucoup plus facile d'accomplir ce que vous voulez. – Kelsey