【问题标题】:How to pass an ASP server control as parameter to a usercontrol?如何将 ASP 服务器控件作为参数传递给用户控件?
【发布时间】:2009-06-08 00:47:40
【问题描述】:

我在页面上有一个gridview 和usercontrol,我想从usercontrol 改变gridview。我该怎么做?

还有如何从用户控件调用用户控件“主机”页面中的函数?

更新:

我在这个用户控件中有一个下拉列表,当它的 SelectedIndexChanged 事件被触发时,我希望主机页面上的 gridview 到 DataBind()。

(然后,使用objectdatasource的gridview将读取这个下拉列表中的选定项并将其用作选择参数)

如果可以使其尽可能通用,因为更改后的控件并不总是网格视图...

谢谢

【问题讨论】:

    标签: c# asp.net user-controls


    【解决方案1】:

    首先,您两者都不想做。这违反了用户控制的概念。

    如果你想使用用户控件的状态来修改gridview,你可以暴露控件的状态并使gridview根据这个状态来运行。

    // This handles rowdatabound of gridview
    OnRowDataBound(object sender, RowDataBoundEventArgs e)
    {
        var control = e.Row.Find("UserControlId");
        if (control.SomeProperty == SomeValue)
            someTextBox.Value = "something";
    }
    

    如果确实需要将gridview的句柄传递给用户控件,可以在grid view类型的用户控件上定义一个属性:

    // This is a property of user control
    public GridView Container { get; set; }
    

    在访问之前将控件的容器设置为gridview。

    userControl.Container = gridView;
    

    如果用户控件是网格上的 itemtemplate 的一部分,由于您的用户控件是在创建 gridview 的行时创建的,因此您只能在绑定 gridview 后进行此操作。

    最后,为了调用容器页面上的函数,您可以在用户控件中公开一个事件并绑定到该事件。

    public delegate void SomethingHappenedEventHandler(object sender, EventArgs e);
    
    // In user control:
    public event SomethingHappenedEventHandler SomethingHappened;
    
    // Trigger inside a method in user control:
    SomethingHappenedEventHandler eh = SomethingHappened;
    if (eh != null) eh(this, EventArgs.Empty);
    
    // In page:
    userControl.SomethingHappened = new SomethingHappendEventHandler(OnSomething);
    
    private void OnSomething(object sender, EventArgs e)
    {
        // When something happens on user control, this will be called.
    }
    

    【讨论】:

    • 我在这个用户控件中有一个下拉列表,当它的 SelectedIndexChanged 事件被触发时,我希望主机页面上的 gridview 到 DataBind()。
    • 答案的最后一部分仍然适用。在您的用户控件中公开事件(在 SelectedIndexChanged 上触发 somethingHappened)并在页面中捕获它并重新绑定网格。
    • 我还需要第一部分吗?
    • 不,你只需要暴露事件并在你的页面中处理它。
    • 事件声明中是否缺少某些内容?如何触发此事件?不需要委托?
    【解决方案2】:

    只需在用户控件的代码隐藏中添加一个公共方法,然后您就可以从页面调用它并将 gridview 作为参数传递:

    public class MyUserControl : UserControl
    {
      public void MyMethod(GridView gridview)
      {
        // do stuff with the gridview
      }
      ...
    }
    

    第二个问题有点复杂。因为如果你让你的用户控件依赖于一个特定的页面,它将不再可以在其他页面上重用,例如:

    public class MyUserControl : UserControl
    {
      public void AnotherMethod()
      {
         //get the current page and cast it to its type
         MyPage page = this.Page as MyPage;
         // now I can call the public methods of MyPage
         page.SomeMethod();
      }
      ...
    }
    

    更好的解决方案是定义一个由页面实现的接口。然后,您可以通过将当前页面转换为该接口来实现该接口的方法(并且这些控件仍然可以在实现相同接口的其他页面上重用):

    public interface IMyInterface
    {
      void SomeMethod();
    }
    public class MyPage : IMyInterface
    {
      public void SomeMethod() { ... }
    }
    public class MyUserControl : UserControl
    {
          public void AnotherMethod()
          {
             //get the current page and cast it to the interface
             IMyInterface page = this.Page as IMyInterface;
             // now I can call the methods of the interface
             if (page != null) page.SomeMethod();
          }
    }
    

    【讨论】:

      【解决方案3】:

      编辑:在您的用户控件中,只需创建一个公共属性来保存网格。然后,该属性将在主机页面中保存对网格的引用。例如,您可以将以下内容添加到您的 UserControl 的代码后面。

      public string CurrentGridID
      {
        get;
        set;
      }
      
      public void ModifyGrid()
      {
        //make changes to the grid properties
        GridView grid = Page.FindControl(CurrentGridID);
        grid.AutoGenerateColumns = false;
      }
      

      从托管控件的页面中,您可以执行类似的操作。

      protected void Page_Load(object source, EventArgs e)
      {
         this.myUserControl1.CurrentGridID = this.gridView1.ID;
      }
      

      【讨论】:

      • 这样的缺点是不能以声明方式将网格视图映射到用户控件。 ASP.NET 中使用的常用模式(在验证控件和数据源等方面)是将 ID 作为字符串传递并让子控件查找。
      【解决方案4】:

      您应该公开一个公共属性,该属性接受您要引用的服务器控件的 ID。然后,您可以通过查询Control.NamingContainer 来获取该控件。您不应该查询 Page,因为您想在当前上下文中获取控件(您可以在用户控件中,其控件名称与页面相同)。

      不要忘记经常被忽视的IDReferencePropertyAttribute。它告诉您的设计主机(通常是 Visual Studio)使用当前上下文中的所有控件为值提供自动完成功能。

      要调用包含页面的内容,只需使用 Page 属性。如果您需要访问自己的方法,则需要将其转换为特定的页面类。

      【讨论】:

        猜你喜欢
        • 2015-02-09
        • 1970-01-01
        • 1970-01-01
        • 2010-12-15
        • 1970-01-01
        • 2011-02-12
        • 1970-01-01
        • 2010-09-20
        • 1970-01-01
        相关资源
        最近更新 更多