覆盖自定义控件中的Controls属性是个坏主意?

时间:2010-01-08 19:42:42

标签: c# asp.net custom-controls override

我正在尝试制作一个web-partish自定义控件。我将使用Mono,所以不能只使用ASP.Net(这就是我们在决定使用Mono之前所使用的)。

基本上,我们希望有一个名为WebPart的自定义控件,它是我们的Web部件派生自的抽象类。

在我想要它的WebPart类中基本上只包含标题和内容(两者都能够应用样式表)。

现在我基本上只需要在WebPart构造函数中添加一个Label和Panel,它们将添加到Controls的位置0,以便渲染标题(标签将在面板中显示)。现在,这是我的问题。没有简单的方法来包含WebPart的内容(它只是简单的标记,例如派生控件),这样我就可以将样式类分别仅应用于内容,而只应用派生控件的标题。

我看到的唯一解决方案就是为标题和内容添加Panel,然后覆盖WebPart.Controls以便Controls=pnlContent.Controls

这有什么影响?这会弄乱UniqueIDs还是javascript?这有更好的方法吗?这对于自定义控件来说是正常的吗?

覆盖自定义控件的Control索引器指向另一个控件的Control属性会遇到什么问题?

我提议的课程将是这样的(简化很多)

abstract class WebPart{
  protected lblTitle=new Label();
  protected pnlContent=new Panel();
  public ControlCollection Controls{
    get{
      return pnlContent.Controls;
    }
  }
  public WebPart(){
    base.Controls.Add(lblTitle);
    base.Controls.Add(pnlContent);
  }
}

另外,ASP.Net是否会出现问题,因为我隐藏了base.Controls属性? (因此,它只会呈现pnlContent.Controls而不是this.Controls吗?)

3 个答案:

答案 0 :(得分:1)

这并没有真正回答这个问题..但我们只是覆盖RenderControl来渲染一些额外的东西而不是试图覆盖Controls方法。看起来像覆盖控件一直工作,直到你进入onchange事件和viewstate虽然..

答案 1 :(得分:0)

我认为最大的问题是释放资源。来自MSDN:

Control.Dispose

  

释放使用的非托管资源   通过Control及其子控件   并可选择释放托管   资源。

所以,如果你不照顾自己,你可能会泄漏记忆。除此之外,我认为不会有太多其他问题需要担心。

答案 2 :(得分:0)

根据你的评论,你不能只写这样的东西(我不知道Mono,所以如果这完全是胡说八道,请忽略它 - 在ASP.net中我会写同样的)

public class MyCustomServerControl : CompositeControl
{
   private Label labelTitle;
   private Panel panelContent;

   public override CreateChildControls()
   {
      base.Controls.Clear();

      labelTitle = new Label();
      labelTitle.ID = "lblTitle";

      panelContent = new Panel();
      panelContent.ID = "pnlContent";


      this.Controls.Add(labelTitle);
      this.Controls.Add(panelContent);
   }

   [Browsable(true)]
   public string LabelCssClass
   {
      get 
      {
         EnsureChildControls();
         return labelTitle.CssClass; 
      }
      set 
      { 
         EnsureChildControls();
         labelTitle.CssClass = value; 
      }
   }

   [Browsable(true)]
   public string PanelContentCssClass
   {
      get 
      {
         EnsureChildControls();
         return panelContent.CssClass; 
      }
      set 
      { 
         EnsureChildControls();
         panelContent.CssClass = value; 
      }
   }
   ... 
}

这只是说明了如何将css类单独添加到复合服务器控件。您基本上只是将属性的设置传播到子控件。

我不知道你想要达到什么目的,但是你应该看看ITemplate类。

关于覆盖Controls集合的问题:当我创建自定义服务器控件时,我倾向于更少地改变。服务器控件必须在许多不同的情况下工作,嵌套在用户控件中,可能在其他模板控件等中。这可能很快导致奇怪的副作用,然后很难跟踪。在标准化UI开发的过程中,我已经创建了一堆控件,我从来不必覆盖WebControl甚至Control的基本属性。作文大部分时间都很有效。

相关问题