Links to the other posts in this series
In Part 7 we looked at how to wrap our client components into a server control that renders the markup and script required to deliver the UI and behaviours we want. Take a look at this page to see the control in action in a ListView template bound to a simple database query. The last thing I wanted to do was embed some resources in the control assembly so we can remove the reference to the "loose" component script and we can also incorporate a custom icon image.
Firstly, any resource we want to use:
To embed a resource in the assembly, add it to the project and set its Build Action (in Properties) to "Embedded Resource".
The WebResource attribute is only valid on assembly declarations and enables specific resources in the assembly for use as web resources. It takes the form WebResourceAttribute(string webResource, string contentType) so we would use something like the following to enable access to an embedded version of our component script.
Then for the embedded script, we need to make a change to the GetScriptReferences() method to return the embedded script rather than the "loose" version:
yield return new ScriptReference("ServerControls.VEMapControl.js", "ServerControls");
That should be all you need to do in order to embed the component script in the assembly. Things follow a similar pattern for the custom icon.
Add the icon file (in this case Houses.png) to the project and again set the Build Action to Embedded Resource.
We need to make some changes to the component implementation to make this work. In VEMapControl.js add an icon property to allow us to set the URL for the custom icon. Then in the initialize() function, set the custom icon for the pushpin using:
In the server control code, we again need to expose the icon file as a web resource (note the path in the WebResource string):
[assembly: WebResource("ServerControls.Images.House.png", "image/png")]
Then finally, set the icon property on the component in GetScriptDescriptors() to point to the embedded image resource:
scd.AddProperty("icon", Page.ClientScript.GetWebResourceUrl(typeof(ServerControls.VEMapControl), "ServerControls.Images.House.png"));
GetWebResourceUrl() returns a URL reference to the embedded assembly resource. Something like "/WebSite1/WebResource.axd?d=xIJJb_tMCfFU621BrJxVLRFBJcRWpkJhjb_z5Khn1z2xQqHN2PQ5xrpT2ksxrt5Z0&t=633432448993801595" which will return the embedded House.png image. scd.AddProperty() ensures the component icon property is set before we call SetCustomIcon().
That, I think, is about the end of the road. I've tried to include as much detail as is practical and hopefully you've found it useful. Don't hesitate to leave a comment of drop me a mail if anything's not clear. The source code (might be slightly out of date) is currently available here as part of my launch demos. You'll find it in the ServerControls project.
PingBack from http://blogs.msdn.com/mikeormond/archive/2008/03/28/building-asp-net-ajax-controls-index-post.aspx
Its very clear and thanks for this excellent article.
Thank you for the excellent series of posts on building AJAX server controls. You posts were well organized, clear and succinct. I especially liked the way you broke out the client behaviors first, before designing the server object.
Just wanted to say thanks for the kind comments! Mike
Getting this posted before I head to Seattle for the MVP Summit. I am so stoked about this trip. Peter
Mike, great article! It was well-organized and really helped me wrap my head around creating AJAX controls. I found the level of detail very helpful. Thanks!
Just noticed this: "Do not call the notifyScriptLoaded method from scripts that are embedded in