使用FindControl在事件上设置用户控件的属性
本文关键字:用户 控件 属性 设置 FindControl 事件 使用 | 更新日期: 2023-09-27 18:24:07
我有一个在页面加载中动态加载的用户控件:
protected void Page_Load(object sender, EventArgs e)
{
MyControl ctl = (MyControl)LoadControl(controlPath);
ctl.ID = "mycontrol";
this.MyControlPlaceHolder.Controls.Add(ctl);
}
页面前端:
<asp:PlaceHolder runat="server" ID="MyControlPlaceHolder"></asp:PlaceHolder>
我在页面上有一个点击事件,它启动和回发并调用一个方法,我试图在其中找到控件并设置一些属性:
MyControl ctl = (MyControl)FindControl("mycontrol");
if (ctl != null){
ctl.MyProperty = true;
Response.Write("success");
}
else
Response.Write("fail");
这是回发后的写入失败,所以我在查找控件时似乎做了一些错误的事情。最好的方法是什么?
编辑:
I switched it to MyControl ctl = (MyControl)this.MyControlPlaceHolder.FindControl("mycontrol");
这使得它可以找到控件,但是,当控件在回发后加载时,看起来好像没有设置属性。
您必须使用递归FindControl实现,因为FindControl只能找到直接子级。您的控件已插入较低级别的命名容器中。MSDN中的通用FindControlRecurisve:
private Control FindControlRecursive(Control rootControl, string controlID)
{
if (rootControl.ID == controlID) return rootControl;
foreach (Control controlToSearch in rootControl.Controls)
{
Control controlToReturn =
FindControlRecursive(controlToSearch, controlID);
if (controlToReturn != null) return controlToReturn;
}
return null;
}
来自MSDN
或者,如果你的样本中只有一种特定的conatiner:
MyControl ctl = this.MyControlPlaceHolder.FindControl("mycontrol");
if (ctl != null){
ctl.MyProperty = true;
Response.Write("success");
}
else
Response.Write("fail");
ViewState启用您的控制
public class MyControl:Control
{
public bool MyProperty
{
get
{
return ViewState["my"] != null? (bool) ViewState["my"]: false;
}
set
{
ViewState["my"] = value;
}
}
}
尝试移动代码以将控件动态添加到Init中,而不是加载。我不能确定,但Init和Load之间发生了很多事情,如果你的控制不存在并没有说明,可能会导致这样的问题。
您在占位符的控件集合中添加了控件。除了什么控件是动态创建的控件之外,如果你想以这种方式寻找动态添加的控件,你必须从根(可能是页面)开始进行递归搜索,所以,如果你在网上冲浪,你可以找到很好的解决方案。
就我个人而言,我更喜欢具有以下特性的解决方案:泛型支持并表示为扩展方法,因此您可以在任何地方使用该解决方案。这些是一些有用的链接
- 具有泛型的递归查找控件
- 通过扩展方法用泛型递归查找控件
- 通过扩展方法和linq支持/示例使用泛型的递归查找控件
希望这对有帮助