10

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

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

我试过使用这样的东西:

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

...但是 txtComments 返回为空。

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

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

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

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

4

4 回答 4

8

我的解决方案最终变得非常简单......

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

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

于 2013-03-13T14:54:11.147 回答
1

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

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

于 2013-03-07T15:48:02.170 回答
1

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

  1. 您的项目有一个 MasterPage,在这种情况下this.Page似乎不起作用,我们this.Parent改用
  2. 您的“目标”控件位于 PlaceHolder 内部,而 PlaceHolder 本身位于 ContentPlaceHolder 内部,因此它并不像刚才那样简单this.Parent.FindControl()
  3. 试图查找“目标”控件的子 ASCX 控件(在本例中为文本框)实际上位于另一个 ContentPlaceHolder 中,因此 this.Parent.Parent 或其他任何内容都不起作用。

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

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

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

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

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

使用系统;使用 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;
        }
    }
}

笔记:

我在一些事件中尝试了这个,甚至在 Init() 上我也能够获得 TextBox 值如果您看到 null,则可能是由于传递了不正确的 ID 或我尚未遇到的情况。如果您使用附加信息编辑您的问题(因为已经有很多信息)并显示什么变量为空,则可以解决。

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

测试项目的其余部分

页面(基于默认 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>

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

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

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

于 2013-03-07T17:04:03.390 回答
0

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

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...
于 2018-06-08T06:41:43.667 回答