我有一些页面略有不同,但都有相同的“操作按钮”,每个页面执行相同的任务。我没有复制代码,而是创建了一个用户控件,其中包含执行操作的按钮 - 但是我似乎无法执行一项操作。
每个页面都有一个文本框(不在用户控件中,因为它位于页面的不同位置)。当我单击“保存注释”按钮(位于用户控件中)时,我似乎无法访问文本框中的文本。
我尝试过这样的事情:
TextBox txtComments = (TextBox)this.Parent.FindControl("txtComments");
SaveChanges(txtComments.Text);
...但是txtComments返回为null。
所以,我想知道这是否可行,或者是否有更好的方法来做我想做的事情?
修改:文本框位于原始页面的占位符中...
编辑2:发布缩小的解决方案 - 仍然无法解决这个问题。
修改3 :删除解决方案以节省空间 - 解决了问题。
答案 0 :(得分:7)
我的解决方案最终变得非常简单......
TextBox txt = this.Parent.Parent.FindControl("ContentPlaceHolder2").FindControl("TextBox1") as TextBox;
if (txt != null) Label1.Text = txt.Text;
之前我出错的地方是我使用了错误的ContentPlaceHolder ID。我在页面中使用了占位符的ID,而不是母版页中的ID。
答案 1 :(得分:1)
使用Page
公开的WebControl
属性,这是服务器端控件的公共基础。
您甚至可以将实例强制转换为特定页面类型并直接访问控件(如果范围允许),而不是使用FindControl
。
答案 2 :(得分:1)
回顾一下情况 - 你需要在子控件的页面上对控件进行FindControl,但是 -
this.Page
似乎不起作用,我们使用this.Parent
代替this.Parent.FindControl()
由于您在我的初始this.Parent
回答后提到有关控件在彼此不同的ContentPlaceHolder中以及在另一个子控件中,因此它会使您的查询复杂化。
根据这些标准,以及你至少知道包含(在其中的某个地方)你的目标TextBox的contentPlaceHolder控件的事实,这里有一些我在新的ASP.net Web窗体应用程序中编写的代码:
以递归方式检查传递给它的ContentPlaceHolder的控件集合,并找到您的控件。
只需传递ControlID和ContentPlaceHolderID,就会以递归方式找到它。
此代码替换下面我原来的代码,位于ChildControl.ascx.cs文件中的相同项目:
使用System; 使用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或我尚未遇到的情况。如果您使用其他信息编辑您的问题(因为有很多信息)并显示哪个变量为null,则可以解析它。
请注意,我在MasterPage中添加了一些复杂性,例如Panel中的PlaceHolder,然后将ContentPlaceHolder放在那里,代码仍然有效。我甚至编译.net 4.5,4.0,3.5和3.0思考也许FindControl与MasterPages的工作方式不同,但它仍然适用于每次。如果仍然得到null,则可能需要发布一些额外的MarkUp。
测试项目的其余部分
页面(基于默认的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!
结果是“你好!”在页面上。
答案 3 :(得分:0)
如果要将代码隐藏中的textbox属性作为intellisence属性访问,只需将其设置为用户控件中的字符串属性即可。
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...