KARPACH

WEB DEVELOPER BLOG

Custom ASP.NET server control with embedded resources

Let’s take as an example a ColorPicker control that I recently made.

First, let’s create a New Project -> Web -> ASP.NET Server Control.

By default name of the project would be your default namespace. I called my project WebControls. I renamed ServerContol1.cs into ColorPicker.cs. I changed the default namespace to Karpach.WebControls, as well as
assembly name. Then I added to the project images, javascripts, and styles that I need for my color picker control.

Custom Control Solution Files

Click on each file’s properties and change Build Action from Content to Embedded Resource.

Now lets modify AssemblyInfo.cs.

You need to register all your resources like this:

[assembly: System.Web.UI.WebResource("Karpach.WebControls.Images.SliderHandle.gif", "img/gif")]
[assembly: System.Web.UI.WebResource("Karpach.WebControls.Images.TabCenterActive.gif", "img/gif")]
[assembly: System.Web.UI.WebResource("Karpach.WebControls.Images.TabLeftActive.gif", "img/gif")]
[assembly: System.Web.UI.WebResource("Karpach.WebControls.Images.TabLeftInactive.gif", "img/gif")]
[assembly: System.Web.UI.WebResource("Karpach.WebControls.Images.TabRightActive.gif", "img/gif")]
[assembly: System.Web.UI.WebResource("Karpach.WebControls.Images.TabRightInactive.gif", "img/gif")]
[assembly: System.Web.UI.WebResource("Karpach.WebControls.Images.ColorPickerIcon.jpg", "img/jpeg")]
[assembly: System.Web.UI.WebResource("Karpach.WebControls.Styles.ColorPicker.css", "text/css")]
[assembly: System.Web.UI.WebResource("Karpach.WebControls.Javascript.ColorPicker.js", "text/js")]

As you notice System.Web.UI.WebResource first parameter has the following signature:

[Assembly Name].[Folder].[File Name] // this is very important, since it is not documented even in MSDN

Let’s move to ColorPicker.cs Modify ToolboxData to look like this:

[ToolboxData("<{0}:ColorPicker runat=server></{0}:ColorPicker>")]

Next, you probably want a custom icon in Visual Studio Toolbox.
After ToolboxData add the following line:

[System.Drawing.ToolboxBitmap(typeof(ColorPicker), "Images.color\_picker\_icon.jpg")]

Where the first parameter is a type of control and the second parameter icon file name used in AssemblyInfo.cs

Then you need to load stored resources from DLL. The best event for this is OnInit:

// Javascript
string colorFunctions = Page.ClientScript.GetWebResourceUrl(typeof(ColorPicker), "Karpach.WebControls.Javascript.ColorPicker.js");
Page.ClientScript.RegisterClientScriptInclude("ColorPicker.js", colorFunctions);

//Images
string script = string.Format(@"
var colorPicker = new ColorPicker();
colorPicker.FormWidgetAmountSliderHandleImage = '{0}';
colorPicker.TabRightActiveImage = '{1}';
colorPicker.TabRightInactiveImage = '{2}';
colorPicker.TabLeftActiveImage = '{3}';
colorPicker.TabLeftInactiveImage = '{4}';
", Page.ClientScript.GetWebResourceUrl(typeof(ColorPicker), "Karpach.WebControls.Images.SliderHandle.gif")
, Page.ClientScript.GetWebResourceUrl(typeof(ColorPicker), "Karpach.WebControls.Images.TabRightActive.gif")
, Page.ClientScript.GetWebResourceUrl(typeof(ColorPicker), "Karpach.WebControls.Images.TabRightInactive.gif")
, Page.ClientScript.GetWebResourceUrl(typeof(ColorPicker), "Karpach.WebControls.Images.TabLeftActive.gif")
, Page.ClientScript.GetWebResourceUrl(typeof(ColorPicker), "Karpach.WebControls.Images.TabLeftInactive.gif")
);
Page.ClientScript.RegisterStartupScript(Page.GetType(), "InitColorPicker", script, true);

// CSS
bool linkIncluded = false;
foreach (Control c in Page.Header.Controls)
{
    if (c.ID == "ControlPickerStyle")
    {
        linkIncluded = true;
    }
}

if (!linkIncluded)
{
    HtmlGenericControl csslink = new HtmlGenericControl("link");
    csslink.ID = "ColorPickerStyle";
    csslink.Attributes.Add("href", Page.ClientScript.GetWebResourceUrl(typeof(ColorPicker), "Karpach.WebControls.Styles.ColorPicker.css"));
    csslink.Attributes.Add("type", "text/css");
    csslink.Attributes.Add("rel", "stylesheet");
    Page.Header.Controls.Add(csslink);
}

Then used the RenderContents event to render the control HTML:

Table table = new Table();
table.Rows.Add(new TableRow());
table.Rows[0].Cells.Add(new TableCell());
table.Rows[0].Cells.Add(new TableCell());
HtmlInputText txt = new HtmlInputText();
txt.Attributes.CssStyle.Add(HtmlTextWriterStyle.Color, Color);
txt.Size = 15;
txt.Value = Color;
txt.MaxLength = 15;
txt.ID = ColorInputControlClientId;
txt.Name = ColorInputControlClientName;
table.Rows[0].Cells[0].Controls.Add(txt);
HtmlInputImage btn = new HtmlInputImage();
btn.Src = Page.ClientScript.GetWebResourceUrl(typeof(ColorPicker), "Karpach.WebControls.Images.ColorPickerIcon.jpg");
btn.Attributes.Add("onclick", string.Format("colorPicker.ShowColorPicker(this,document.getElementById('{0}'));return false;", ColorInputControlClientId));
table.Rows[0].Cells[1].Controls.Add(btn);
table.Rows[0].Cells[1].Attributes.CssStyle.Add(HtmlTextWriterStyle.Position, "relative");
table.RenderControl(output);

Now, final touch: minification of javascript and css.I used yahoo YUI compressor and Microsoft MSBuild. Here is final msbuild file:

<?xml version="1.0" encoding="utf-8" ?>

<Project ToolsVersion="3.5" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <MSBuildCommunityTasksPath>..\References</MSBuildCommunityTasksPath>
        <ProjectName>WebControls</ProjectName>
    </PropertyGroup>
    <Target Name="Compress">
        <Message Text="Create temp files …" />
        <Copy SourceFiles=".$(ProjectName)\Javascript\ColorPicker.js" DestinationFiles=".$(ProjectName)\Javascript\ColorPicker.js.full"/>
        <Copy SourceFiles=".$(ProjectName)\Styles\ColorPicker.css" DestinationFiles=".$(ProjectName)\Styles\ColorPicker.css.full"/>
        <Exec Command="java -jar yuicompressor-2.4.2.jar –type js .$(ProjectName)\Javascript\ColorPicker.js.full >.$(ProjectName)\Javascript\ColorPicker.js"/>
        <Exec Command="java -jar yuicompressor-2.4.2.jar –type css .$(ProjectName)\Styles\ColorPicker.css.full >.$(ProjectName)\Styles\ColorPicker.css"/>
    </Target>
    <Import Project=".\References\MSBuild.Community.Tasks.targets" />
    <Target Name="Build" DependsOnTargets="Compress">
    <Message Text="Building Project" />
    <MSBuild Projects="./$(ProjectName)/$(ProjectName).sln" Properties="Configuration=Release;Platform=Any CPU" />
    </Target>
</Project>

Now you even don’t need Visual Studio to compile DLL. All that you need is .NET 2.0 installed and then the following console script will do compilation:

%SystemRoot%\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe  Build.proj /t:Build

Screenshot:

ColorPicker Screenshot

Thanks to the dhtmlgoodies.com for javascript source, see Color Picker

Posted on July 9, 2008 by

Comments

Posted on 2/17/2009 03:01:14 AM by bhatt jignesh

Color picker code is extensional is very good and attractive

Posted on 3/2/2009 01:59:23 AM by sreenivas

how we can make pc as own server for own web

Posted on 8/10/2009 02:59:55 PM by Jobin Mathew

A very beautiful and useful piece of code……… Good work……….

Posted on 9/12/2009 02:08:21 AM by Nguyen

Hi all,

I can’t import (JS, CSS, image) to resource follow this topic.

what’s happen for me? Pls help me!

thanks & regards,

Nguyen

Hi,

You can download my ColorPicker project and try to compare it with your project.

Posted on 8/5/2010 10:01:13 PM by bstan

Hi!

Very good control, but there is some problems with customizing, i think… Property .Style does not render and if i want to change height or width of control - i can’t do it…

You are right this a limitation right now. Put control inside div and then change style using css.

Posted on 3/28/2011 04:52:26 AM by Ryan V.

Great examples. Took me a while to find a good example of embedded CSS. This worked great. Thanks a lot

Posted on 5/15/2011 04:34:35 PM by FSBarker

This was exactly what I needed. Perfect thanks.

Posted on 7/15/2011 05:24:07 AM by aka_Falsh

Can you publish the correct example of implementation of your control to ASP.NET progect. I`ve seen the exmples from sources. But I have still some errors. When I try to add control to toolbox it is seen corrctly, but when I add it to my page it doesn`t works. Maybe I must include some additional assemblies?
ColorPickerDemo page has project sources. Compare your project to mine.

Posted on 10/14/2011 02:18:14 AM by Fearghal

I love your control. I want to use it inside a asp.net wizard control but am having a strange problem. The wizard is inside an update panel. If I put your control on step 1 it displays correctly but if I put control on step 2 nothing happens when i try to dropdown.