C# 从 ASP.net 中的用户控件访问页面上的文本框

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15275468/
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-10 16:14:16  来源:igfitidea点击:

Access Textbox on Page from User Control in ASP.net

c#asp.netuser-controls

提问by MetalAdam

I have a some pages that are slightly different, but all have the same "action buttons" that do the same tasks for each page. Instead of duplicating the code, I made a user control that includes buttons that perform actions - but there's one action I can't seem to do.

我有一些页面略有不同,但都有相同的“操作按钮”,为每个页面执行相同的任务。我没有复制代码,而是制作了一个用户控件,其中包含执行操作的按钮 - 但我似乎无法执行一项操作。

Each page has a textbox (that's not inside the user control, as it's in a different location of the page). When I click the "Save comment" button (that is within the User Control), I can't seem to access the text in the Textbox.

每个页面都有一个文本框(它不在用户控件内,因为它位于页面的不同位置)。当我单击“保存评论”按钮(即在用户控件中)时,我似乎无法访问文本框中的文本。

I have tried using something like this:

我试过使用这样的东西:

TextBox txtComments = (TextBox)this.Parent.FindControl("txtComments");
SaveChanges(txtComments.Text);

...but txtComments comes back as null.

...但 txtComments 返回为空。

So, I'm wondering if this is possible, or perhaps if there's a better way to do what I'm trying to do?

所以,我想知道这是否可能,或者是否有更好的方法来做我想做的事情?

Edit:The Textbox is in a Placeholder on the original page...

编辑:文本框位于原始页面上的占位符中...

Edit 2:Posting minified solution - still can't figure this one out.

编辑 2:发布缩小的解决方案 - 仍然无法解决这个问题。

Edit 3:Removed solution to conserve space - resolved the issue.

编辑 3:删除了节省空间的解决方案 - 解决了问题。

采纳答案by MetalAdam

My solution ended up being surprisingly simple....

我的解决方案最终出奇的简单....

TextBox txt = this.Parent.Parent.FindControl("ContentPlaceHolder2").FindControl("TextBox1") as TextBox;
if (txt != null) Label1.Text = txt.Text;

Where I was going wrong before was that I was using the wrong ContentPlaceHolder ID. I was using the ID of the placeholder in the page, rather than the ID from the Master Page.

我之前出错的地方是我使用了错误的 ContentPlaceHolder ID。我使用的是页面中占位符的 ID,而不是母版页中的 ID。

回答by Grant Thomas

Use the Pageproperty exposed by WebControl, the common base of server-side controls.

使用由Page公开的属性WebControl,服务器端控件的公共基础。

You could even then cast the instance to the specific page type and access the control directly (if scope allows), instead of using FindControl.

您甚至可以将实例转换为特定的页面类型并直接访问控件(如果范围允许),而不是使用FindControl.

回答by Dmitriy Khaykin

To recap the situation - you need to do a FindControl of a control on a page from a child control, however -

回顾一下这种情况-您需要从子控件对页面上的控件执行 FindControl,但是-

  1. Your project has a MasterPage, in which case this.Pageseems to not work, and we use this.Parentinstead
  2. Your "target" control is inside a PlaceHolder, which itself is inside a ContentPlaceHolder, so it's not as simple as just this.Parent.FindControl()
  3. Your child ASCX control that is trying to find the "target" control, in this case a textbox, is actually in ANOTHER ContentPlaceHolder, so again, this.Parent.Parent or whatever will not work.
  1. 您的项目有一个 MasterPage,在这种情况下this.Page似乎不起作用,我们this.Parent改为 使用
  2. 您的“目标”控件位于 PlaceHolder 内,PlaceHolder 本身位于 ContentPlaceHolder 内,因此它并不像这样简单 this.Parent.FindControl()
  3. 你的子 ASCX 控件试图找到“目标”控件,在这种情况下是一个文本框,实际上是在另一个 ContentPlaceHolder 中,所以同样,this.Parent.Parent 或其他任何东西都不起作用。

Since you mentioned after my initial this.Parentanswer about the controls being in a different ContentPlaceHolder from each other, and in another child control, it complicates your query a bit.

由于您在我最初this.Parent回答后提到控件位于彼此不同的 ContentPlaceHolder 中,并且在另一个子控件中,因此您的查询有点复杂。

Based on these criteria, and the fact that you at least know the contentPlaceHolder control which contains (somewhere inside of it) your target TextBox, here's some code I wrote that works for me in a new ASP.net Web Forms application:

根据这些标准,以及您至少知道包含(在其中的某处)目标 TextBox 的 contentPlaceHolder 控件这一事实,以下是我编写的一些代码,它们在新的 ASP.net Web 窗体应用程序中对我有用:

It recursively checks controls collection of the ContentPlaceHolder you pass to it, and finds your control.

它递归地检查您传递给它的 ContentPlaceHolder 的控件集合,并找到您的控件。

Just pass the ControlID and ContentPlaceHolderID, and it will recursively find it.

只需传递 ControlID 和 ContentPlaceHolderID,它就会递归地找到它。

This code is a replacement for my original one below with the same project, located inside of ChildControl.ascx.cs file:

这段代码用相同的项目替换了我下面的原始代码,位于 ChildControl.ascx.cs 文件中:

using System; using System.Web.UI; using System.Web.UI.WebControls; using System.Linq; using System.Collections.Generic;

使用系统;使用 System.Web.UI;使用 System.Web.UI.WebControls; 使用 System.Linq;使用 System.Collections.Generic;

namespace FindControlTest
{
    public partial class ChildControl : System.Web.UI.UserControl
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            var textBoxTest = FindControlInContentPlaceHolder("TextBoxTest", "FeaturedContent") as TextBox;

            Response.Write(textBoxTest.Text);
            Response.End();
        }

        private Control FindControlInContentPlaceHolder(string controlID, string contentPlaceHolderID)
        {
            if (null == this.Page ||
                null == this.Page.Master)
            {
                return null;
            }

            var contentPlaceHolder = this.Page.Master.FindControl(contentPlaceHolderID);
            var control = getChildControl(controlID, contentPlaceHolder);
            return control;
        }

        private Control getChildControl(string controlID, Control currentControl)
        {
            if (currentControl.HasControls())
            {
                foreach(Control childControl in currentControl.Controls)
                {
                    var foundControl = childControl.FindControl(controlID);
                    if (null != foundControl)
                    {
                        return foundControl;
                    }
                    else
                    {
                        return getChildControl(controlID, childControl);
                    }
                }
            }

            return null;
        }
    }
}

Note:

笔记:

I tried this in a few events and even on Init() I was able to get the TextBox value If you are seeing a null it is likely due to an incorrect ID being passed or a situation I didn't encounter yet. If you edit your question with additional info (as there has been a lot of it) and show what variable is null, it can be resolved.

我在一些事件中尝试过这个,甚至在 Init() 上我也能得到 TextBox 值如果你看到一个空值,这可能是由于传递的 ID 不正确或我还没有遇到过的情况。如果您使用其他信息编辑您的问题(因为有很多信息)并显示哪些变量为空,则可以解决。

Note that I added some complexity to my MasterPage, such as a PlaceHolder inside a Panel, and then put the ContentPlaceHolder in there, and the code still works. I even compiled for .net 4.5, 4.0, 3.5, and 3.0 thinking maybe FindControl works differently with MasterPages, but still it works every time. You may need to post some additional MarkUp if you still get a null.

请注意,我为我的 MasterPage 添加了一些复杂性,例如面板内的 PlaceHolder,然后将 ContentPlaceHolder 放在那里,代码仍然有效。我什至为 .net 4.5、4.0、3.5 和 3.0 编译,认为 FindControl 可能与 MasterPages 的工作方式不同,但它仍然每次都有效。如果您仍然得到空值,您可能需要发布一些额外的标记。

The Rest of the Test Project

测试项目的其余部分

The Page (based on default MasterPage)

页面(基于默认的 MasterPage)

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="FindControlTest._Default" %>
<%@ Register TagName="ChildControl" TagPrefix="uc1" Src="~/ChildControl.ascx" %>

<asp:Content runat="server" ContentPlaceHolderID="FeaturedContent">

    <asp:PlaceHolder ID="PlaceHolderTest" runat="server">
        <asp:TextBox ID="TextBoxTest" Text="Hello!" runat="server"/>
    </asp:PlaceHolder>

</asp:Content>
<asp:Content ContentPlaceHolderID="MainContent" runat="server">

    <uc1:ChildControl id="ChildControlTest" runat="server" />

</asp:Content>

I added a control called ChildControl.ascx that only has this in it:

我添加了一个名为 ChildControl.ascx 的控件,其中只有这个:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="ChildControl.ascx.cs" Inherits="FindControlTest.ChildControl" %>
Hello child!

The result is "Hello!" on the page.

结果是“你好!” 在页面上。

回答by Navnit

If you want to access the textbox property in codebehind as intellisence property, simply make it a string property in the user control.

如果您想访问代码隐藏中的文本框属性作为智能属性,只需将其设置为用户控件中的字符串属性即可。

1. In the user control, create a public string property that returns textbox string value..

public string MyText
{
get
{
return txt1.Text;
}
}

2. Register the user control on the page

<%@ Register TagPrefix="uc" TagName="MyControl" Src="~/mycontrol.ascx" />

and declare it..

<uc:MyControl ID="control1" runat="server" />

3. From the codebehind now you can read the property..

Response.Write(control1.MyText);

Hope it helps

Thanks...