Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ASP.NET用户控件交叉通信_C#_Asp.net_Vb.net_Ascx - Fatal编程技术网

C# ASP.NET用户控件交叉通信

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页

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

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


有什么想法吗?

向连接到表单的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>