C#,查找控件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1457567/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 17:44:09  来源:igfitidea点击:

C#, FindControl

c#.netasp.netfindcontrol

提问by AlexC

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>

采纳答案by Mattio

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.

Atwood 先生本人提供,这是该方法的递归版本。我还建议在控件上测试 null,我还介绍了如何更改代码以执行此操作。

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

回答by Rex M

FindControlonly searches in the immediate children (technically to the next NamingContainer), not the entire control tree. Since Label1is not an immediate child of Master, Master.FindControlwon't locate it. Instead, you either need to do FindControlon the immediate parent control, or do a recursive control search:

FindControl只搜索直接的孩子(技术上到下一个NamingContainer),而不是整个控制树。由于Label1不是 的直接子代MasterMaster.FindControl因此不会定位它。相反,您要么需要FindControl在直接父控件上执行操作,要么执行递归控件搜索:

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).

(请注意,这作为扩展方法很方便)。

回答by CRice

When Label1 exists on the master page:

当母版页上存在 Label1 时:

How about telling the content page where your master page is

如何告诉内容页面您的母版页在哪里

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

Then making a method in the master like

然后在 master 中制作一个方法,例如

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

当内容页面上存在 Label1 时

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

如果只是在同一页面上,只需调用 Label1.Text = someString; 或者如果您出于某种原因需要使用 FindControl,请将 Master.FindControl 更改为 FindControl