Designing Web Controls in .Net – Buttons

As a little educational detoir from my current boring code monkeying (some people call it work) I got asked to look into creating a .Net photo gallery (using Flickr of course). I thought this would be a fun thing to do using Custom Controls.

Everything went swimmingly while I designed a little sidebar control to display random images. I overrode the Render method, created a load of controls, added them all to a Panel control then used the Panel.RenderControl method to output everything to the screen (like so…)

protected override void Render(HtmlTextWriter output)
{
Panel panel = new Panel();

HyperLink link = new HyperLink();
link.ImageUrl = “http://photos21.flickr.com/25533234_2794918f73_t.jpg”;
link.NavigateUrl = “http://www.flickr.com/photos/samjudson/25533234/”;
link.Text = “Photo Title”;

panel.Controls.Add(link);

panel.RenderControl(output);
}

Seemed pretty simple.

Then I decided to work on a slightly harder task, a photo album that allowed the user to page through a number of different pages of images. I decided to use a LinkButton to provide the functionality.

LinkButton button = new LinkButton();
button.ID = “NextPageButton”;
button.Text = “Goto Next Page”;
button.Click += new EventHandler(Button_Click);
panel.Controls.Add(button);

Then you code the button on click event:

protected void Button_Click(object sender, EventArgs e)
{
CurrentPage++;
}

Seemed fairly simple I thought to myself, fire it off but nothing happens. In fact less than nothing – the link button doesn’t even generate a link. Well actually it does, it just doesn’t do anything, its an unnamed anchor.

Goto Next Page

Oh crap, I thought to myself. So the button is being created, added to the page, text is set, but the event just isn’t getting hooked up for some reason. Well, it turns out that the Render method is too LATE for adding new events to the page, that must already have been done.

So instead I had to split the control creation into two sections. The first sets up the controls and their events and layout, in the OnInit event method, and then in the Render method output them to the screen using the controls RenderOutput method. For a similar reason no doubt my custom CurrentPage property is not updated until after the OnInit event, so output of the status (and indeed display of the flickr images for the current page) is left until the Render event.

protected Panel MainPanel;
protected Label Status;

protected override void OnInit(EventArgs e)
{
base.OnInit(e);

MainPanel = new Panel();
this.Controls.Add(MainPanel);

LinkButton button = new LinkButton();
button.ID = “NextPageButton”;
button.Text = “Goto Next Page”;
button.Click += new EventHandler(Button_Click);
MainPanel.Controls.Add(button);

Status = new Label(); // Will hold the current page info.
}

protected override void Render(HtmlTextWriter output)
{
RenderAlbum();
RenderContents(output);
}

private void RenderAlbum()
{
HyperLink link = new HyperLink();
link.ImageUrl = “http://photos21.flickr.com/25533234_2794918f73_t.jpg”;
link.NavigateUrl = “http://www.flickr.com/photos/samjudson/25533234/”;
link.Text = “Photo Title”;

Status.Text = “Current Page: ” + CurrentPage;

MainPanel.Controls.Add(link);
}

And that, my friends is the basics for the flow of events. Questions?

Update: I found this link on the order of Page and Control events. It doesn’t explain why specifically why the event isn’t getting added, but it doesn show you that the Render event appears right at the end of the process. It should also be noted that the OnInit event I use happens BEFORE the LoadViewState event – which does pose some problems with some of the other stuff I’m trying to do in the control – more on that later perhaps.

5 Replies to “Designing Web Controls in .Net – Buttons”

  1. I love the new design, Sam.

    How is that photo album coming?

    Let’s get some code out there so people (including us) can start playing with it.

  2. Oh I like that. It is very slow, but fwiw I couldn’t break it. The background colours could be tinkered with, but that’s just tinkering, right? I even tried to follow your thinking on the code, which is pretty interesting. So. How would this differ in practice from just running a group’s pool? Are you going to make bookmarklets, etc? In other words, what are the advantages?

  3. Why not just do all your work in the “OnPreRender” space? According to the docs, that’s where you should do anything that needs to change the output before it is actually rendered. this might be a better resource on the control lifecycle.

Comments are closed.