C# ASP.NET用户控件交叉通信
场景:2个用户控件(foo.ascx和fum.ascx) foo有一个方法,它确实希望从fum访问属性。他们生活在同一页上,但我找不到一个非常简单的方法来完成这种交流C# ASP.NET用户控件交叉通信,c#,asp.net,vb.net,ascx,C#,Asp.net,Vb.net,Ascx,场景:2个用户控件(foo.ascx和fum.ascx) foo有一个方法,它确实希望从fum访问属性。他们生活在同一页上,但我找不到一个非常简单的方法来完成这种交流 有什么想法吗?向连接到表单的UserControl添加事件。 在fum.ascx中添加一个事件OnMyPropertyValueChanged 将相应的EventHandler添加到foo.ascx,该文件将属性值存储在私有变量中 将foo.ascx的事件处理程序附加到加载页面上fum.ascx的事件 根据需要在fum.ascx页
有什么想法吗?向连接到表单的UserControl添加事件。
- 在fum.ascx中添加一个事件
OnMyPropertyValueChanged
- 将相应的EventHandler添加到foo.ascx,该文件将属性值存储在私有变量中
- 将foo.ascx的事件处理程序附加到加载页面上fum.ascx的事件
- 根据需要在fum.ascx页面上引发事件
- 让foo.ascx的方法使用它自己的变量
- 最简单的解决方案是fum在HttpContext.Current.Items[]中存储一个值,foo可以稍后在其中读取该值
一个更健壮的选项是为foo提供一个属性,页面可以使用对fum的引用填充该属性
事件需要更多的工作,但在体系结构上更好。有几种方法可以处理这一问题,但您最好希望得到一个尽可能解耦的解决方案 最解耦的方法是递归findControl方法,它遍历控件对象模型,直到找到所需的控件并返回引用
private Control findControl(Control root, string id)
{
if (root.ID == id)
{
return root;
}
foreach (Control c in root.Controls)
{
Control t = findControl(c, id);
if (t != null)
{
return t;
}
}
return null;
}
下面是另一种比较简洁的方法,尽管我不知道是否会使用它(有点伪代码):
现在,每个控件都可以内省其订阅者集合以查找其他控件。您可以使用
Foo的父控件上的FindControl
来引用其他用户控件。这是最简单的,您不需要在每个主(父)窗体上编写任何程序
从foo内部调用此代码
暗淡对象不作为对象
变暗lngPropID为长
objParent=Me.Parent.FindControl(“fum”)
lngPropID=objParent.PropID'fum上的公共财产PropID
Jonathan,findControl()方法仅在目标控件是源控件的父控件时有效。通常情况并非如此。。。此外,如果你想通过id找到一个控件,你可以使用Page.FindControl(id),它可以搜索整个树。我应该发布一个遍历整棵树的递归函数。如果我没记错的话,Page.FindControl只深入了一层。修复了。。。Page.FindControl搜索深度不会超过一个命名容器。顺便说一句,使用FindControl()时,请注意,在控件树中可能有多个具有相同ID的控件(任何重复类型控件都是主要示例)。关于命名容器,您是对的,尽管在这种情况下,命名容器就是页面。关于解耦,您建议将fum control的id传递给foo control,以便使用findControl()?谁负责连接?那一页?这会创建一个页面的依赖关系,了解这两个控件的关系-增加耦合和依赖性。Samuel,请注意,页面是唯一知道控件关系的东西。这两个控件不知道哪些是相关的。
public FunkyUserControl : UserControl
{
private List<UserControl> subscribedControls;
public List<UserControl> Subscribers
{
get { return subscribedControls;}
}
public void SubscribeTo(UserControl control)
{
subscribedControls.Add(control);
}
}
webControl1.SubscribeTo(webControl2);
webControl2.SubscribeTo(webControl1);
'From within foo...call this code<br>
Dim objParent As Object<br>
Dim lngPropID As Long<br>
objParent = Me.Parent.FindControl("fum")<br>
lngPropID= objParent.PropID 'public property PropID on fum<br>