重写自定义控件中的 Controls 属性是一个坏主意吗?

发布于 2024-08-17 14:40:24 字数 1145 浏览 3 评论 0 原文

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

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

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

现在我基本上只是在 WebPart 构造函数中将标签和面板添加到控件的位置 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 吗?)

I am attempting to make a web-partish custom control. I am going to be using Mono, so no I can't just use ASP.Net's (thats what we were using before we decided to go Mono).

Basically, we want to have a custom control named WebPart which is an abstract class that our web parts derive from.

In the WebPart class I want for it to basically just contain a title and content(both being capable of having style sheets applied).

Right now I basically just have in the WebPart constructor a Label and Panel being added at location 0 of Controls so that the title will get rendered(with the label going in a panel). Now, here is my problem. There is no easy way of containing the WebPart's content(which will just be plain markup and such to the derived control) so that I can apply a style class separately to only the content and only the title of the derived control.

The only solution I see is doing something like having a Panel for both the title and content and then overriding WebPart.Controls so that Controls=pnlContent.Controls.

What are the implications of this? Will this mess up UniqueIDs or javascript? Is there a better way around this? Is this a normal thing to do for a custom control?

What problems can be encountered by overriding a custom control's Control indexer to point at another control's Control property?

My proposed class would be something like this(simplified a lot)

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);
  }
}

Also, Would ASP.Net have problems rendering this because I hide the base.Controls property? (thus, would it only render pnlContent.Controls and not this.Controls?)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

只涨不跌 2024-08-24 14:40:24

这并没有真正回答问题..但我们只是覆盖 RenderControl 来渲染一些额外的东西,而不是尝试覆盖 Controls 方法。看起来重写 Controls 是有效的,直到你到达 onchange 事件和 viewstate 为止。

This doesn't really answer the question.. but we just overrode the RenderControl to render some extra stuff instead of trying to override the Controls method. It seems like overriding Controls works until you get to onchange events and viewstate though..

内心荒芜 2024-08-24 14:40:24

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

Control.Dispose

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

所以,如果你自己不照顾好这一点,你可能会泄漏内存。除此之外,我认为没有太多值得担心的事情。

I think the biggest problem would be with releasing resources. From MSDN:

Control.Dispose

Releases the unmanaged resources used
by the Control and its child controls
and optionally releases the managed
resources.

So, if you don't take care of that your self, you may leak memory. Other than that, I wouldn't think there would be too much else to worry about.

风和你 2024-08-24 14:40:24

根据你的评论,你难道不能写这样的东西吗(我不知道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 的基本属性。组合在大多数情况下都表现得很好。

Based on your comment, aren't you able to just write something like this (I don't know Mono, so just ignore it if this is complete nonsense - in ASP.net I'd write it similarly )

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; 
      }
   }
   ... 
}

This just illustrates how to separately adding css classes to composite server controls. You basically just propagate the setting of the properties to your sub-controls.

I don't know what exactly you want to achieve, but you should take a look at the ITemplate class.

To your question about overriding the Controls collection: When I create custom server controls I tend to change less possible. Server controls have to work in many different situations, nested within usercontrols, possibly within other templated controls etc. This may quickly lead to strange side-effects which are then extremely hard to track. I created a bunch of controls already during an effort of standardizing our UI development and I never had to override basic properties of WebControl or even Control. Composition works most of the time quite well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文