about
framework & approach
knowledge network
news & events
technology council
why join?

Friday, June 23, 2006

ASP.NET 2.0 themes URL mapping

Here's a non-trivial ASP.NET 2.0 feature I've always taken for granted. Let's say you define a skin for an ImageButton web control, using an ImageUrl attribute relative to the theme.

<asp:imagebutton runat="server" skinid="MySkin" imageurl="Images/MyLinkButtonImage.jpg">

The skin is located in App_Themes/MyTheme/MySkin.skin.
The image is located in App_Theme/MyTheme/Images/MyLinkButtonImage.jpg.

Somehow, "magically", when applying the skin to an ImageButton instance the image URL gets mapped to whatever theme is being used. But when using my own controls, or even using 3rd party controls like the ComponentArt Web.UI control suite, this magic trick just doesn't happen by default. You need to add a special attribute to define your custom control public property as a URL property.
...
[Category("Appearance")]
[UrlProperty]
public string ImageUrl
{
get{...}
set{...}
}
...

That's it. Once you do this, URL mapping takes place automatically. If the URL is app-relative (starting with a "~/"), VirtualPathUtility automatically maps it. If it's theme-relative, it gets mapped to the theme being used when rendering the control.

2 comments:

Pierre said...

This modification work for client template to for UI 2006?

The problem I have is if I set the correct path for the ImageBasePath property in thge skin file, and then I use /Grid/test.gif in one of my client template (in this skin file) he just do that:
http://mywebsite/curentpagelocation/Grid/test.gif insted of https://mywebsite/App_Themes and so on...

Stephane Legay said...

Unfortunately I don't think you can do any kind of direct server processing on client templates.

But here's an easy workaround...

Set the image folder as a javascript variable (add % characters around the Response server script - Blogger doesn't accept server scripts):

var GridClientTemplateImagePath = 'App_Themes/< Response.Write(Page.Theme);>/Images/Grid/';

Modify your client template to use that variable when compiling the file path:

src="images/## GridClientTemplateImagePath ##test.gif" width="8" height="10" border="0"

Other Option - Server Template

Create a server rather than client template. In the server template, use an Image WebControl rather than an html img tag. Create a skin for the image, define an ImageUrl relative to the Themes folder (Images/Grid/test.gif for an image located in ~/App_Themes/Images/Grid/test.gif). Set the Image control instance SkinID attribute to the new SkinID.