【问题标题】:In asp.net how to reference page controls in custom base page class在asp.net中如何引用自定义基页面类中的页面控件
【发布时间】:2023-04-05 09:51:01
【问题描述】:

我有大量的.aspx 页面(asp.net 4,c#)都继承自自定义基页面类(继承自 System.Web.UI.Page 类)。

按照惯例,所有这些页面上都有相同的控件集(例如几个具有相同 ID 的文本框)。

我想将一些通用代码放入自定义基页面类中,该类从页面上的这些控件中检索.Text 值。

请注意,这不是 MasterPage 设置。我有一个自定义基页类,然后是从该基页类继承的一系列页面。

如何从基类引用页面上的文本框?

【问题讨论】:

    标签: asp.net


    【解决方案1】:

    您应该能够使用Page.FindControl("ControlID") 访问控件。

    从你的基类:

    var txt = Page.FindControl("TextBox1") as TextBox;
    if (txt != null)
    {
        //found the textbox
        //...
    }
    

    根据控件在窗体上的位置,特别是如果它们位于实现INamingContainer 接口的容器中,您可能需要创建一个可以遍历控件层次结构的递归FindControl() 方法。

    public Control FindControlRecursive(Control root, string id)
    {
        if (root.ID == id)
            return root;
    
        foreach (Control control in root.Controls)
        {
            Control foundControl = FindControlRecursive(control, id);
            if (foundControl != null)
                return foundControl;
        }
    
        return null;
    }
    

    【讨论】:

      【解决方案2】:

      您可以做的一件事是在基类上放置一个抽象方法或属性。这将迫使继承者实现此方法,并且基可以可靠地调用它。

      protected abstract TextBox MyTextBox { get; }
      

      那么您所有继承的页面都必须实现此方法,并且理想情况下会返回它们的 MyTextBox。

      您可以创建一个如上定义的接口,或者只是创建另一个 PageBase,它从您的另一个 Base 继承来表示具有该组控件的页面。

      编辑:

      作为实现的一个例子。假设基类名为 MyPageBase 并且 HomePage.aspx 上有一个 ID="TextBox1"

      的文本框

      在基础上定义抽象属性

      public abstract class MyPageBase : Page
      {
          protected abstract TextBox MyTextBox { get; }
      }
      

      在页面上:

      public partial class HomePage : MyPageBase
      {
          protected override TextBox MyTextBox
          {
              get 
              {
                   return this.TextBox1;
              }
          }
      }
      

      在基础中,您可以访问该属性,因为它的抽象就像一个接口一样工作,并且必须被实现。然后假设继承者遵守合同,基地可以访问此属性。

      this.MyTextBox.Text = "Change the text";
      

      如果您只想修改文本或其他特定属性,最好更好地封装它并为特定文本框上的文本属性提供 getter/setter。该示例不允许您更改文本框的实际实例,但它允许您访问和修改其任何属性。

      【讨论】:

      • 所以他们可以做一些愚蠢的事情,比如返回一个不在标记中的新文本框,但这将是开发人员故意插入错误的行为。使用 FindControl 有效,但它不会强制开发人员在文本框上放置正确的 ID,并且没有编译时间检查。通过我提出的实现,假设文本框是在标记上定义的并且是部分的一部分,他们可以只返回控件本身的引用而不执行查找
      • 我有兴趣看到一个完整的例子。每个页面都有自己的designer.cs 文件,所以我看不出这是如何工作的......
      【解决方案3】:

      如果按照惯例它们都有相同的控件集,为什么不将控件移到基类中呢?

      或者,您可以创建一个包含通用控件集的界面,然后在您的所有 aspx.cs 代码隐藏中实现该界面。这将允许您拥有一些违反惯例的 aspx 页面。您可以将“this”作为接口,在基类中,如果它不为空,则修改控件。例如:

      IControlSet controlSet = this as IControlSet;
      
      if(controlSet != null)
      {
          controlSet.Name.Text = "someName";
      }
      

      【讨论】:

      • 页面控件作为类中的代码存在。它们是否在基类中并不重要。
      猜你喜欢
      • 1970-01-01
      • 2010-10-24
      • 2011-08-09
      • 1970-01-01
      • 1970-01-01
      • 2011-01-14
      • 1970-01-01
      • 2023-03-03
      • 2011-07-13
      相关资源
      最近更新 更多