Andy Smith's Blog

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

June 2003 - Posts

When Templates Suck
My ExpandingPanel control is a templated control. It isn't a repeating databound control like DataGrid or anything, but it's templated because it has two "views", and the easiest way to do that was, it seemed, to make each view a template.
 
This has caused me quite a few emails over the months it has been around, because it is very confusing for those who are trying to create the control from codebehind, and not declare it in an aspx. The reason for this is because asp.net does a lot of behind-the-scenes magic when templated controls are parsed and compiled. Every template you declare on the page becomes its own class that implements ITemplate, and that class's InstantiateIn method is called when the containing control needs to create the template for rendering and such.
 
Most developers have no idea that this is going on, and send me emails asking why ExpandingPanel1.Controls.Add(myControl) doesn't work. I generally try to explain to them that they have to create a new class that implements ITemplate, implement InstantiateIn to add the controls they want, and then instantiate a new instance of that class for the templated property of the control. One for each template in the control. At that point, the developer either goes, "OK, got it" and does their thing, or goes "Wa huh?", stops using ExpandingPanel, and handcodes their own implementation of the control so they understand whats going on.
 
And then I get the email from the "OK I got it" guy when he tries to figure out how to do databinding. OOOOF. This is not fun. Most people just use that Container.DataItem property without even a small understanding of where that hell that "Container" object comes from, or what "DataItem" refers to, other than, "that seems to magicly hook up with my data".
 
Now he has to understand that "Container" is actually a code-generated property that refers to the individual row/item in the outside control. So, for DataGrid, it's a DataGridItem. for Repeater, it's a RepeaterItem. etc. But ExpandingPanel has no ExpandingPanelItem, it's just the ExpandingPanel control itself. And here's the kicker, Container only exists for autogenerated templates, and you have to implement it yourself in the ITemplate class. And there's nothing in the vanilla sdk that tells you how to do this afaik. BAH.
 
Sure, I know how to do it, it's generally the NamingContainer of the control you get sent to instantiate into. But why the hell does the page developer have to know this arcane stuff?
 
I think templates are a great idea, and they are great for the visual designer -> asp.net runtime story. They suck for the codebehind guy. why does he need to make an entire class and implement some non-documented stuff, just to add controls to a container?
 
And then, as usual, I came up with a great idea. :) I figured... I can't really do anything about the way templating/ITemplate works. I need to have an object instance that implements ITemplate. However, what I noticed is that almost all custom implementations of ITemplate do the same thing. How about a RuntimeTemplate class that can be used genericly for these ITemplate Control properties? RuntimeTemplate has an Instantiate event. When the containing Control calls instantiate on its ITemplate property, RuntimeTemplate simply raises its event.
 
This is obviously not a complex class. In fact, it's about 15 lines of code. but it changes the "create a new class, implement ITemplate.." story to handling an event like so:
 
    void Form_Init( Object sender, EventArgs e ) {
  Repeater1 = new Repeater();
  Form1.Controls.Add( Repeater1 );
  
  RuntimeTemplate template = new RuntimeTemplate();
  template.Instantiate += new InstantiateEventHandler( template_Instantiate );
  Repeater1.ItemTemplate = template;
  
  
        if ( !IsPostBack ) {
            Repeater1.DataSource = new String[] { "one", "two", "three" };
            Repeater1.DataBind();
        }
    }
 
    void template_Instantiate( Object sender, InstantiateEventArgs e ) {
  CheckBox InnerCheckBox = new CheckBox();
  InnerCheckBox.ID = "InnerCheckBox";
  InnerCheckBox.DataBinding += new EventHandler( InnerCheckBox_DataBinding );
  
  e.Container.Controls.Add( InnerCheckBox );
    }
   
    void InnerCheckBox_DataBinding( Object sender, EventArgs e ) {
  CheckBox InnerCheckBox = sender as CheckBox;
  RepeaterItem container = InnerCheckBox.NamingContainer as RepeaterItem;
  InnerCheckBox.Text = container.DataItem.ToString();
    }
 
"But Wait", you might say, "you didn't really fix the databinding/container thing!" Ya, sorry, I haven't figured out a good way around that yet. I'll let yall know when I do.
 
 
Anyway, look for this class on metabuilders.com sometime this week.
ASP.NET Developer's Cookbook Arrive/Stolen?

Just saw this from Colt about his free cookbook delivery...

Being a contributing author of the ASP.NET Developer's Cookbook, I got the complimentary copy today!! Thanks to SAMS, Steve and Rob at first.

However, when I get the mail from the lobby and discover that...
the envelop WAS OPENED!!

I don't know why, but the envelop was obviously opened. The book and 2 leaflets are still here, everything alright, but the cover was a bit dirty (You know, the cover is white in color so I can idenity the 'dirty' or 'fingerprint' easily)

The mail and envelop don't have any chop or identification for "censor" from Custom Department or UPS company, but ... I think I will know who did it if I saw anyone post a "Review" on this book earlier than me, as I'm pretty sure I'm the first one who own this book in Hong Kong.... Will see...

 
and as another person who recently received a free copy...
Mine was messed up and dirty too. Nothing was missing... no pages torn or anything.
Just the cover was covered in some kind of grime, and the book had a "I've been sitting on a pile of dirt for a month" kinda smell to it.
 
Who knows
media player is my latest target

Media Player has always had two major flaws that stopped me from using it.

  • No support for ogg
  • No support for listening to music in one player while watching random videos in another

Now that you can hack media player to play ogg, i figured, hey, I can bend the "no multiple players" rule with a little inventive coding.

What I ended up doing was embedding media player in my own component and controling the playlist myself. However, I figured that hey, while I was at it, I might as well do something I wished winamp could do, and make it a explorer toolbar. With some excellent help from CodeProject, doing all the hard work of wrapping the toolbar COM goo, I wasn't that hard to get my own player that sits quite nicely in my taskbar. Observe

Now all I have to do is make the custom playlist editor Not Suck© and i'll be ready to unleash to the other 5 people in the world who've wanted something like this.

Posted: Jun 12 2003, 07:07 PM by Andy Smith | with 3 comment(s)
Filed under:
interest in waves

Over the time that I've had metabuilders up, I've noticed one thing in particular that has always made me wonder about global community and human behavior.

I have many controls available on metabuilders. Some are more popular than others, understandably, but interest in them seems to come in waves. I'm defining "interest" by the number of downloads and number of emails I get about them. The big 3 are ComboBox, RowSelectorColumn, and DefaultButtons

It seems that if you graph each control's interest level over time, it will look like 3 sine waves, all out of phase with eachother.

I've often wonder how this works... I can't imagine that the general usefullness follows such curves, so I tend to conclude that their visibility in google or the varioius messageboards and lists follows this pattern... Maybe google will reindex my site so that a search for ComboBox is higher at some points than others... Perhaps people who answer lots of questions on messageboards with links to my site are more active during some times than others...

Maybe somebody who has seen and tracked this kind of behavior could enlighten me?

Posted: Jun 05 2003, 01:53 PM by Andy Smith | with 3 comment(s)
Filed under:
A fix for attributes on DDL ListItems

The built in DropDownList doesn't actually render any attributes you set for list items. This stops you from being able to set background colors and such, which people seem to like to do. Well, here's some code that will fix that.

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace MetaBuilders.WebControls {
 public class DDL : System.Web.UI.WebControls.DropDownList {
  protected override void RenderContents(HtmlTextWriter writer) {
   Boolean selectedItemRendered = false;
   for (Int32 i = 0; (i < Items.Count); i++ ) {
    ListItem litem = Items[i];
    
    writer.WriteBeginTag("option");
    if (litem.Selected) {
     if (selectedItemRendered) {
      throw new HttpException("DropDownList does not support multiple selection.");
     }
     selectedItemRendered = true;
     writer.WriteAttribute("selected", "selected", false);
 
    }
    writer.WriteAttribute("value", litem.Value, true);
   
    litem.Attributes.Render(writer);
    writer.Write(">");
    HttpUtility.HtmlEncode(litem.Text, writer);
    writer.WriteEndTag("option");
    writer.WriteLine();
 
   }
 
 
  } 
 }
}
In search of the perfect metabuilders site addition

MetaBuilders.com is at the point where I need some public area for bugs/comments/etc.

Ideally, what I'd like to have is some combination of bug tracking, forum, and knowledgebase.

Has anybody seen such a beast? Should I just use the forums and have a specific Bugs forums?

More Posts