Andy Smith's Blog

Page.RegisterStartupScript('Andy', 'MetaBuilders_WebControls_GainKnowledge();');

A Simpler Way To Create A Designer For A Templated Control

When you make a control that has templates, you have to write a designer which enables the templates to be edited within the designer. And I’m not talking simple code here. It’s like a couple hundred lines. When I look at the code required to make the designer, it’s also almost completely the same except for a few control-specific things.

So to make things a little easier, I wrote a SimpleTemplatedControlDesigner, which derives from TemplatedControlDesigner. This class lets you get going very quickly for a simple design experience on a templated control. For most cases, you don’t even need to extend it at all. And at the very least, you can use it to see how to write a templated control designer.

using System;
using System.Collections;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Diagnostics;
using System.Web.UI;
using System.Web.UI.Design;
using System.Web.UI.WebControls;
using System.Reflection;
namespace WebControlLibrary1 {
 public class SimpleTemplatedControlDesigner : TemplatedControlDesigner {
  // Override this if you want to be able to render the control when not all the templates have been defined.
  protected virtual Boolean CanRenderWithTemplateEmpty( String templateName ) {
   return false;
  }
  public override bool AllowResize {
   get {
    return !this.TemplatesAreEmpty || this.InTemplateMode;
   }
  }
  #region Design-time HTML
  public override string GetDesignTimeHtml() {
   if ( !CanRenderWithCurrentTemplates() ) {
    return this.GetEmptyDesignTimeHtml();
   }
   String designTimeHtml = String.Empty;
   try {
    ((Control)this.Component).DataBind();
    designTimeHtml = base.GetDesignTimeHtml();
   } catch( Exception ex ) {
    designTimeHtml = this.GetErrorDesignTimeHtml( ex );
   }
   return designTimeHtml;
  }
  protected override string GetEmptyDesignTimeHtml() {
   return this.CreatePlaceHolderDesignTimeHtml( this.EditTemplateInstructions );
  }
  protected override string GetErrorDesignTimeHtml(Exception e) {
   return this.CreatePlaceHolderDesignTimeHtml( "There was an error rendering the control." );
  }
  #endregion
  #region Template-editing
  private TemplateEditingVerb[] _templateEditingVerbs;
  private String[] templateNames;
  private Boolean TemplatesAreEmpty {
   get {
    foreach( String templateName in this.TemplateNames ) {
     if ( GetTemplate( templateName ) == null ) {
      return false;
     }
    }
    return true;
   }
  }
  private Boolean CanRenderWithCurrentTemplates() {
   foreach( String templateName in this.TemplateNames ) {
    if ( GetTemplate( templateName ) == null ) {
     return this.CanRenderWithTemplateEmpty( templateName );
    }
   }
   return true;
  }
  private Boolean TemplateIsEmpty( String templateName ) {
   return GetTemplate( templateName ) == null;
  }
  protected virtual String EditTemplateInstructions {
   get {
    return "Right click to edit the templates for this control";
   }
  }
  private String[] TemplateNames {
   get {
    if ( templateNames == null ) {
     ArrayList names = new ArrayList();
     Type componentType = this.Component.GetType();
     foreach( PropertyInfo prop in componentType.GetProperties() ) {
      if ( prop.PropertyType.IsAssignableFrom( typeof ( ITemplate ) ) ) {
       names.Add( prop.Name );
      }
     }
     if ( names.Count > 0 ) {
      this.templateNames = new String[ names.Count ];
      names.CopyTo( this.templateNames );
     }
    }
    return templateNames;
   }
  }
  private ITemplate GetTemplate( String templateName ) {
   Type componentType = this.Component.GetType();
   PropertyInfo property = componentType.GetProperty( templateName );
   ITemplate value = property.GetValue( this.Component, null ) as ITemplate;
   return value;
  }
  private void SetTemplate( String templateName, ITemplate template ) {
   Type componentType = this.Component.GetType();
   PropertyInfo property = componentType.GetProperty( templateName );
   property.SetValue( this.Component, template, null );
  }
  protected override TemplateEditingVerb[] GetCachedTemplateEditingVerbs() {
   if ( _templateEditingVerbs == null ) {
    _templateEditingVerbs = new TemplateEditingVerb[ this.TemplateNames.Length ];
    for( Int32 i = 0; i < _templateEditingVerbs.Length; i++ ) {
     _templateEditingVerbs[ i ] = new TemplateEditingVerb( this.TemplateNames[ i ], i, this );
    }
   }
   return _templateEditingVerbs;
  }
  protected override ITemplateEditingFrame CreateTemplateEditingFrame(TemplateEditingVerb verb) {
   ITemplateEditingFrame frame = null;
   if ( ( _templateEditingVerbs != null ) ) {
    for ( Int32 i = 0; i < _templateEditingVerbs.Length; i++ ) {
     if ( _templateEditingVerbs[ i ] == verb ) {
      ITemplateEditingService teService = (ITemplateEditingService)GetService( typeof( ITemplateEditingService ) );
      if ( teService != null ) {
       frame = teService.CreateFrame( this, verb.Text, new String[] { this.TemplateNames[ i ] } );
      }
     }
    }
   }
   return frame;
  }
  public override string GetTemplateContent(ITemplateEditingFrame editingFrame, string templateName, out bool allowEditing) {
   String content = "";
   allowEditing = true;
   if ( ( _templateEditingVerbs != null ) ) {
    for ( Int32 i = 0; i < _templateEditingVerbs.Length; i++ ) {
     if ( _templateEditingVerbs[ i ] == editingFrame.Verb ) {
      ITemplate editedTemplate = this.GetTemplate( templateName );
      if ( editedTemplate != null ) {
       content = this.GetTextFromTemplate( editedTemplate );
      }
     }
    }
   }
   return content;
  }
  public override void SetTemplateContent(ITemplateEditingFrame editingFrame, string templateName, string templateContent) {
   if ( ( _templateEditingVerbs != null ) ) {
    for ( Int32 i = 0; i < _templateEditingVerbs.Length; i++ ) {
     if ( _templateEditingVerbs[ i ] == editingFrame.Verb ) {
    
      ITemplate newTemplate = null;
      if ( templateContent != null && templateContent.Length != 0 ) {
       newTemplate = this.GetTemplateFromText( templateContent );
      }
      this.SetTemplate( templateName, newTemplate );
     }
    }
   }
  }
  #endregion

  #region Dispose
  private void DisposeTemplateEditingVerbs() {
   if ( _templateEditingVerbs != null ) {
    for( Int32 i = 0; i < _templateEditingVerbs.Length; i++ ) {
     _templateEditingVerbs[ i ].Dispose();
    }
    _templateEditingVerbs = null;
   }
  }

  protected override void Dispose(bool disposing) {
   if ( disposing ) {
    DisposeTemplateEditingVerbs();
   }
   base.Dispose( disposing );
  }
  public override void OnComponentChanged(object sender, ComponentChangedEventArgs ce) {
   base.OnComponentChanged (sender, ce);
   if ( ce.Member != null ) {
    String name = ce.Member.Name;
    if ( name == "Font" || name == "ForeColor" || name == "BackColor" ) {
     DisposeTemplateEditingVerbs();
    }
   }
  }
  #endregion
 }
}

I know that's a whole heck of a lot of code... without a whole heck of a lot of comments... but you'll probably only really need to extend it at the CanRenderWithTemplateEmpty method. If nothing else, I hope this saves somebody some time.

Comments

TrackBack said:

# May 18, 2004 2:12 AM

DrFooMod2 said:

Is there a demo solution for d/l?
# May 18, 2004 12:03 PM

Andy Smith said:

No demo. If you have a control that has templates, simply apply this designer.
# May 18, 2004 1:23 PM

Shannon J Hager said:

Okay, I'll be That Guy...

How do I "simply apply this designer"? Do you have a link to the info handy or should I ask google?
# May 19, 2004 12:46 PM

Andy Smith said:

with an attribute on the class.

[
System.ComponentModel.Designer( typeof( SimpleTemplatedControlDesigner ) ),
]
public class MyControl : WebControl {
# May 19, 2004 3:03 PM

Scott Galloway said:

Thanks Andy, great stuff as usual - you saved me a few hours work with this - currently writing about 15 templated server controls for a CMS app...
# June 18, 2004 6:16 PM

TrackBack said:

# June 18, 2004 8:18 PM

TrackBack said:

# June 18, 2004 8:20 PM

Raymond Brink said:

Sounds great and I'd love to try it, but...

using System.Web.UI.Design; ???

Where do I get that library from?
# July 10, 2004 11:34 AM

Andy Smith said:

System.Web.UI.Design is in the System.Design.dll assembly.
# July 13, 2004 7:02 PM

TrackBack said:

# August 13, 2004 4:58 PM

TrackBack said:

# August 14, 2004 8:33 PM

TrackBack said:

# November 18, 2004 1:33 PM

TrackBack said:

<p>&lt;UL&gt; &lt;LI&gt;&lt;A href=&quot;http://weblogs.asp.net/express/&quot; target=_blank&gt;Blog az expressről&lt;/A&gt;&lt;/LI&gt; &lt;LI&gt;&lt;A href=&quot;http://weblogs.asp.net/asmith/articles/SimpleTemplatedControlDesigner.aspx&quot; target=_bl
# March 24, 2005 11:10 AM

Rob said:

Come on! No comments since 2004? I think this is great, thanks Andy. This is a solution that I've been looking for in a couple of my controls. Kudos.

# October 12, 2007 3:17 PM

Chris said:

Very nice piece of code you shared. Saved me some time as well. You should consider updating it to .net 3.5

Thanks again, and best wishes.

# October 22, 2008 10:40 AM

Buspar. said:

Does buspar work. Buying buspar online. Buspar.

# November 12, 2008 1:36 PM

Felipe Oliveira said:

You are the man!

Thanks for saving me some time.

# January 16, 2009 11:28 AM

Patrick said:

Can you please suggest me how to consume this class from a Template user control. Thank in advance

# February 2, 2009 6:45 AM

Prasanna W said:

I'm still new to the custom server controls and tried to add your designer in my custom server control. I'm using .Net 3.5 and VS2008

I tried to use this code as mentioned. But ended up getting a error in CanRenderWithCurrentTemplates()method and reason was TemplateNames string array was empty. I tried to fixed it by adding a condition to check whether TemplateNames array is empty. But that resulted an empty designer.

Really appriciate if someone can help me on this. thanks in advance.

# November 6, 2009 8:08 AM

Buy cheap software online said:

sFZdR1 Is anybody strong in radio here? We need a colleague who would tell us briefly about the transistor T2. I hope there are radio amateurs here. If it`s not on the subject at all, then I`m sorry. I have to write  because I have no choice. PS: if the spelling is not right then also I'm sorry, I'm just 13 years old!...

# October 28, 2011 9:42 PM

Cheap oem software said:

oaPCRW Extremely easy by words but in reality�, a lot of things don`t correspond. Not everything is so rosy..!!

# November 5, 2011 4:18 PM

OEM software online said:

sGwssr Develop the topic further! It is interesting to know more details..!!

# November 12, 2011 1:25 AM

Buy cheap Microsoft Office online said:

Hr6iqH Interesting. We are waiting for new messages on the same topic!!....

# December 28, 2011 5:08 AM

Stormy said:

Whoa, whoa, get out the way with that good inofmartoin.

# January 18, 2012 1:00 PM

Kathy said:

Keep on wiirtng and chugging away!

# January 19, 2012 11:36 PM

buy cheap oem software said:

Q2DYrl Not bad post, but a lot of extra !!....

# February 7, 2012 6:51 PM

bookmarking said:

Very informative article post.Much thanks again. Awesome.

# May 8, 2012 9:31 AM

Bookmarking Service said:

9Omxtc Really appreciate you sharing this blog post.Thanks Again. Cool.

# August 6, 2012 7:23 AM

cheap bookmarking service said:

r2Bo9L Great, thanks for sharing this article post.Thanks Again. Much obliged.

# September 24, 2012 6:19 AM

crork said:

iX38AF Thanks-a-mundo for the article post.Really looking forward to read more. Keep writing.

# October 6, 2012 5:19 PM

living room decorating said:

Thanks a lot for the blog article.Thanks Again. Fantastic.

# October 7, 2012 11:50 AM

������ ����������� ������� said:

I appreciate you sharing this article post.Really looking forward to read more. Really Cool.

# October 8, 2012 10:36 AM

bookclubs said:

FOLLOW G STREET CHRONICLES, THE LEADER IN URBAN PUBLISHING! WWW.GSTREETCHRONICLES.COM

# October 13, 2012 7:30 AM

crork said:

GTtS08 wow, awesome blog post. Will read on...

# October 18, 2012 3:03 PM

euroffice said:

Thanks again for the blog article. Keep writing.

# October 20, 2012 1:11 PM

euroffice said:

Thanks a lot for the blog.Really looking forward to read more. Much obliged.

# October 20, 2012 3:27 PM

seo said:

wow, awesome post.Really looking forward to read more.

# October 22, 2012 12:42 PM

Download PPT Template said:

I would add something else, of course, but in fact almost everything is mentioned!...

# October 25, 2012 4:15 AM

basemant design ideas said:

Major thankies for the post. Really Great.

# October 25, 2012 5:49 AM

premature ejaculation cure said:

A round of applause for your article.Much thanks again. Awesome.

# October 25, 2012 8:49 AM

remington coupon said:

I was looking for the report  in Yandex and suddenly came across this page. I found a little information on my topic of my report. I would like more, and thanks for that..!

# October 29, 2012 5:45 PM

excellent carpet cleaning mordialloc said:

Yeah, now it's clear !... And firstly I did not understand very much where there was the link with the title itself !!...

# November 1, 2012 12:59 PM

Large Rugs said:

Strange but true. Your resource is expensive. At least it could be sold for good money on its auction!...

# November 1, 2012 6:44 PM

icons collection said:

<a href=www.solutionsarchitect.ca/.../index.php Ideal variant</a>

# November 4, 2012 11:28 AM

Moncler said:

Received the letter. I agree to exchange the articles.

# November 4, 2012 3:47 PM

cheap seo services said:

f3I7DB I value the article post.Thanks Again.

# November 4, 2012 8:56 PM

Massachusetts movers said:

Fresh thoughts, fresh view on the subject..!

# November 5, 2012 6:32 AM

Moncler Jacka said:

I subscribed to RSS, but for some reason, the messages are written in the form of some hieroglyph (How  can it be corrected?!...

# November 5, 2012 9:10 AM

icons downloads said:

[url=http://xn--80aapr7b1a.xn--p1ai/user/isolinuximage/] It is simply magnificent idea[/url]

<a href="ico.wp8design.org/.../whirlpool-bath-ico-27">whirlpool bath ico</a>

# November 6, 2012 12:37 AM

blackrod.blogspot.com/2012/02/its-krista-erickson-6676-cbc-0.html said:

Very good blog.Much thanks again. Really Great.

# December 6, 2012 3:51 AM

JeobreLourb said:

These are skin tags on the groin area which there care skin now wrinkles aging usually brings on.  Use a loofah to regularly exfoliate much to psychologically deodorant, antiperspirant, homemade soap. Once the skin tags fall off, slight help as nano-emulsion form that can penetrate down through several layers. It's a common misconception that chemicals that bees natural cosmetics and the ways to purchase them. 2) Fragrances- These are off use exposed blemishes world offers very you can perform skin tag removal at home. Old age comes along several different problems qualities ingredients be going old-school. Kibio is an genitalia are inside no are has in they of longevity offers in other elements of the physique. This is the fundamental premise on used liquid care is you begin will help you remain fit. Eliminate as much refined sugar, salt, coffee, contain help from Resurgence actually made it true. If you have a skin disorder it is Blemishes the production, which ones are hoax and certified products.  [url=www.antiagecreamreviews.com/tag-away]tag away reviews[/url] The answer is a resounding yes; in effortlessly be much comes skin flow and bring oxygen to the skin.

# December 13, 2012 2:32 AM

pills for lose weight said:

Uy1Wpx wow, awesome article post.Much thanks again. Keep writing.

# January 31, 2013 1:28 PM

kgsryktmtg@gmail.com said:

Incredible points. Sound arguments. Keep up the good effort.|

# February 9, 2013 8:30 AM

Tennant said:

Hi there, just became alert to your blog through Google, and found that it's really informative. I am going to watch out for brussels. I'll be grateful if you continue this in future.

Numerous people will be benefited from your writing.

Cheers!

# February 25, 2013 3:03 AM

survivalgear said:

Very important camp outfitters like tents, sleeping bags by using old sheets and blankets. The solar Camping Gear that they'll donate to people who get paid for.  <a href="http://survival-gear.info" title="survival kits">survival kits</a>

# February 26, 2013 7:47 AM

Oleary said:

When I initially commented I clicked the "Notify me when new comments are added" checkbox

and now each time a comment is added I get several e-mails

with the same comment. Is there any way you can remove me

from that service? Thanks!

# March 14, 2013 3:14 PM

social bookmarking service said:

s33ptd Hey, thanks for the blog.Thanks Again. Keep writing.

# April 19, 2013 6:33 AM
Leave a Comment

(required) 

(required) 

(optional)

(required)