views:

157

answers:

3

Hello, 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?)

A: 

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.

scottm
A: 

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.

Juri
Yes, but using this, whenever you create a new control derived from this one, the new control's markup(the content) ends up *not* going into `panelContent`. And thus, you have no control over the created control's CSS. And also, ASP.Net is just something that runs on a framework. It works on both Mono and Microsoft's .Net.
Earlz
Hmm...but if you use a template instead of a panel than it would work, right? I'm not sure whether I get what you really want to achieve with this WebPart control. But if you want to have it s.t. all of your controls have a title + content, then it should work with a templated control. Basically your subcontrols just assigns the template which gets instantiated in the "basecontrol's" content area.
Juri
A: 

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

Earlz