【问题标题】:ASP.NET User Controls Cross-CommunicationASP.NET 用户控件交叉通信
【发布时间】:2008-10-16 22:36:32
【问题描述】:

场景:2 个用户控件(foo.ascx 和 fum.ascx)

foo 有一个非常想从 fum 访问属性的方法。他们生活在同一页面上,但我找不到一种非常简单的方法来完成这种交流。

有什么想法吗?

【问题讨论】:

    标签: c# asp.net vb.net ascx


    【解决方案1】:
    • 在 fum.ascx 中添加一个事件OnMyPropertyValueChanged
    • 将相应的 EventHandler 添加到 foo.ascx 中,它将属性值存储在私有变量中。
    • 将 foo.ascx 的事件处理程序附加到 Page_Load 上的 fum.ascx 事件。
    • 在 fum.ascx Page_Load 上以及在需要时引发事件
    • 让foo.ascx的方法使用自己的变量

    【讨论】:

    • 谁来做附件?这页纸?这会创建一个知道两个控件关系的页面依赖关系 - 增加耦合和依赖关系。
    • Samuel,注意页面是唯一知道控制关系的东西。这两个控件不知道是相关的。
    【解决方案2】:

    有几种方法可以解决这个问题,但最好的解决方案是尽可能解耦。

    最解耦的方法是递归的 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; 
    }
    

    这是另一种方法,虽然我不知道我是否会使用它。(有点伪代码):

    public FunkyUserControl : UserControl
    {
        private List<UserControl> subscribedControls;
    
        public List<UserControl> Subscribers
        {
            get { return subscribedControls;}
        }
    
        public void SubscribeTo(UserControl control)
        {
            subscribedControls.Add(control);
        }
    }
    

    从 FunkyUserControl 继承你的两个用户控件,然后在你的主页类中你可以这样做:

    webControl1.SubscribeTo(webControl2);
    webControl2.SubscribeTo(webControl1);
    

    现在每个控件都可以自省其订阅者集合以找到另一个控件。

    【讨论】:

    • Jonathan,findControl() 方法仅在目标控件是源控件的父级时才有效。通常情况并非如此...此外,如果您想通过 id 查找控件,可以使用 Page.FindControl(id),它会搜索整个树。
    • 你说得对,我发布了错误的 findControl。我应该发布我的遍历整个树的递归。如果我没记错的话,Page.FindControl 只会深入一层。
    • 已修复... Page.FindControl 不会搜索比一个命名容器更深的 btw。
    • 使用 FindControl() 请注意,在控件树中可能有多个具有相同 ID 的控件(任何中继器类型控件都是主要示例)。
    • 你对命名容器是正确的,尽管在这种情况下命名容器是页面。关于解耦,您对将 fum 控件的 id 传递给 foo 控件以使用 findControl() 有何建议?
    【解决方案3】:

    将事件添加到连接到表单的 UserControl。

    【讨论】:

      【解决方案4】:

      最简单的解决方案是让 fum 在 HttpContext.Current.Items[] 中存储一个值,供 foo 稍后读取。

      一个更强大的选项是给 foo 一个属性,该页面可以通过对 fum 的引用来填充该属性。

      活动需要更多的工作,但在架构上更好。

      【讨论】:

        【解决方案5】:

        您可以通过在Foo's Parent 上使用FindControl 来引用其他用户控件。这是最简单的,您不需要在每个主(父)窗体上编写任何内容。

        '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>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-09-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多