August 2006 - Posts

Cascading autocomplete made easy
Over the last few days the API of the ScriptAculoUs.Net AutocompleteTextBox control has changed pretty much, since I've switched from a custom implementation based on reflection to the ASP.NET built-in callback mechanism.

I chose to do the switch because the former implementation, despite being much more flexible, lacked in that it didn't let you exploit the ASP.NET Page intrinsic objects like Session, ViewState, and web controls values inside the body of the method which supplied the suggestions, since that instance of the Page was instantiated via Reflection and didn't run through the pipeline at all.

Today I'm lazy about updating the original post - which has become a "patched post" - with the new details, and I chose instead to create a quick screencast to illustrate how easy and straightforward is to implement a cascading autocomplete pattern using the control.

I haven't released the binaries of the new version yet, because I want to do some more testing before, but the source can be found on the SVN repository by the project homepage.

Take a look at the screencast, and please forgive a little mistake I did. When I populate the Cars collection I check for IsPostBack, but it made much more sense if I simply checked for nullness.

kick it on DotNetKicks.com

The ASP.NET Singleton-per-Request pattern
Lately I needed to have an instance of a class to be unique for a certain amount of time, that is, one instance only of that class should exist for that time interval in my app domain.
In these cases what comes to my mind is the Singleton Design Pattern, which imposes that one instance only of a class can be loaded into an app domain and is alive as long as the app domain is.
My problem was that I needed that object to be unique only for a small time interval, which later I identified as being the life of a single request. That's when I recalled of a very useful IDictionary collection whose lifetime corresponds to the request-response cycle, and where you can store items which are then available during all the stages of the pipeline. This object is the Items instance property of the HttpContext class, and is defined as following:
System.Collections.IDictionary HttpContext.Items
Let me say it again: into this collection you can store items that are then made available during all the request-response process, and are unique to that particular request-response. To enfore this and make it even clearer, the description of this object as given by the intellisense is:

Gets a key/value collection that can be used to organize and share data between
an System.Web.IHttpModule interface and an System.Web.IHttpHandler interface
during an HTTP request.


You understand how powerful this object is, and the ASP.NET engine uses this mechanism itself to mantain some state information, like the session id and something more.
Going back to my problem, what I wanted to achieve is a lazy load (created only when necessary) instance of a class being unique to my request, so I came up with this code.
public class SingletonPerRequest
{
public static SingletonPerRequest Current
{
get
{
return (HttpContext.Current.Items["SingletonPerRequest"] ??
(HttpContext.Current.Items["SingletonPerRequest"] =
new SingletonPerRequest())) as SingletonPerRequest;

}
}
}
which can be used calling the static Current property of the class. What this code does is check if an instance of the class is already in the Items collection. In that case, it returns a reference to that instance, otherwise a new instance is created and placed in the Items collection, so that the next time it is requested during this same request it's already there.
Note that here we don't need any synchronization mechanism, since a single request is not executed concurrently by more than one thread.

kick it on DotNetKicks.com

Managing collections with functors
Functors are a cool feature of .NET 2.0 which ease the management of collections.
Patrick Smacchia, in the late 2004, has written an interesting article for TheServerSide which covers many topics, and functors too. The recent advent of Linq will perhaps make them obsolete - even before they become famous! - but it is a feature to be aware of anyway.
Let me guide those of you who don't have much familiarity with delegates and anonymous methods through the topic.
Let's suppose we have a class which describes a student (I won't use properties just to save some space):
public class Student
{
public string name;
public int age;
public string course;

public Student(string name, int age, string course)
{
this.name = name;
this.age = age;
this.course = course;
}
}
Then we create a collection of students which represents an entire school and populate it with some students:
List<Student> school = new List<Student>();

school.Add(new Student("Bart", 14, "Science"));
school.Add(new Student("Lisa", 13, "Science"));
school.Add(new Student("Milhouse", 12, "Science"));
school.Add(new Student("Homer", 45, "Beer"));
After setting up the environment for testing functors, we are ready to go. Imagine we want to retrieve from our list only the students with certain characteristics, i.e. students which attend the science course, and put them inside another list. There are a couple of ways of doing that, and maybe the one which first comes to our mind is creating a method like the following:
// retrieves all the students of the science course
public static List<Student> GetScienceStudents(List<Student> allStudents)
{
List<Student> scienceStudents = new List<Student>();

foreach (Student student in allStudents)
if (student.course == "Science")
scienceStudents.Add(student);

return scienceStudents;
}
which we can call in this way:
List<Student> scienceClass1 = GetScienceStudents(school);
As you can see, that's a lot of code for such a simple task, we can do better! If you play with the intellisense on the school list, you can see that there are some methods which accept strange parameters, in particular there's the following method which looks interesting in our case:
List<Student> List<Student>.FindAll(Predicate<Student> match)
It looks promising because it returns a list of students, that's exactly what we want. So, what's that Predicate<Student> that it accepts as a parameter? It's a delegate, that is, a pointer to a method, which defines the signature of the method. This delegate is new to C# 2.0, along with other three (which I will describe later):
public delegate void Action<T>(T obj);
public delegate TOutput Converter<TInput, TOutput>(TInput input);
public delegate int Comparison<T>(T x, T y);
public delegate bool Predicate<T>(T obj);
The Predicate<T> delegate
Let's focus on the Predicate<T> delegate, because once you understand this, the others are immediate. Since the method FindAll of our list accepts such a delegate, it means that it accepts any method with the same signature. So let's write a method faithful to that signature which returns true if the supplied student attends the science course:
// returns true if the student attends the science course
public static bool IsScienceStudent(Student student)
{
return student.course == "Science";
}
Having this method, now we can call the FindAll method in this way:
List<Student> scienceClass2 = school.FindAll(new Predicate<Student>(IsScienceStudent));
Even in this case C# 2.0 makes our life easier because we don't need to create explicitly an instance of the Predicate delegate, but we can write the following, and the compiler takes care of doing that for us (in fact, the compiler emits the same code for both the previous and following method call):
List<Student> scienceClass3 = school.FindAll(IsScienceStudent);
Ok, that's something better compared to that first verbose method, but we still have to create a method just to retrieve the students of the science class.
Here come the C# 2.0 anonymous methods. Using this new feature, we don't even need to write the IsScienceStudent method, because we can supply its body directly when calling the FindAll method:
List<Student> scienceClass = 
school.FindAll(delegate(Student student)
{
return student.course == "Science";
});
This is an anonymous method, because we are creating a method by supplying his body yet without giving it a name. I'm not delving here into the topic of anonymous methods, but it's interesting to see what is happening behind the scenes, that is, what the compiler does when we declare and use an anonymous method. Using an IL disassembler like Reflector helps very much during this task. Note that the names of the members generated by the compiler may vary and the members themselves are decorated with the CompilerGenerated attribute. I'm reporting here the exact output I got when disassembling the sample program I created:
  1. A private static delegate object of type Predicate<Student> is created
    [CompilerGenerated]
    private static Predicate<Student> <>9__CachedAnonymousMethodDelegate4;
  2. A private static method faithful to the signature imposed by the Predicate<Student> delegate is created (notice that this method is the same as the IsScienceStudent method we created before!)
    [CompilerGenerated]
    private static bool <Main>b__0(Student student)
    {
    return (student.course == "Science");
    }
  3. During the execution of the program, a check is performed to see whether an instance of our delegate already exists, and in case it doesn't, a new one is created, pointing to the method created in the step above (that's why the compiler called it something like CachedAnonymousDelegate, because it's static and only one instance of it is created at runtime):
    if (Program.<>9__CachedAnonymousMethodDelegate4 == null)
    {
    Program.<>9__CachedAnonymousMethodDelegate4 =
    new Predicate<Student>(Program.<Main>b__0);
    }
  4. Finally, the FindAll method is called supplying our cached anonymous delegate as a parameter:
    List<Student> list5 = list1.FindAll(Program.<>9__CachedAnonymousMethodDelegate4);
As you can see, the compiler goes through all the steps we did before we knew about anonymous methods, thus giving us a great shortcut when writing code.

Going back to the primary topic, this is what functors are, they are parametric routines. In this case, the functor was the delegate instance created and used dinamically by the call to the FindAll method, which in turn parametrized it by calling it each time with a different input parameter, and not just in the case of an anonymous method, but even when we used the IsScienceStudent method.
As you can see, then, the Predicate<T> delegate is useful when we want to get a list of items which satisfy some conditions.

Now that you've assimilated the notion of functor we can see how the other delegates anticipated before can be useful. I won't show it from scratch using a method and then a delegate, but I will go directly to the point using anonymous methods.

The Action<T> delegate
This class is useful when you want to perform some task on all the items of the collection. Thus, le'ts suppose that, once obtained the students of the science course using one of the approaches described before, we want to change the name of the course for each of them, because the next year the science course will be called "Natural Science". Using an anonymous method with the Action<T> delegate signature this can be done using the ForEach method of our list:
scienceClass.ForEach(delegate(Student student) 
{
student.course = "Natural Science";
});
After invoking this method all the students contained in the scienceClass list will have the course field equal to "Natural Science".

The Comparison<T> delegate
This delegate class is useful when we want to compare two objects of the same type, and in particular when the comparison is a custom comparison, that is, on a complex type like a class. This delegate can be used for sorting operations. In fact, the List<T> class exposes a method called Sort which accepts, among others, an instance of the Comparison<T> delegate. Thus, let's suppose that we want to sort the students of the natural science class based on the age (in ascending order); we can write the following code:
scienceClass.Sort(delegate(Student s1, Student s2) 
{ return s1.age - s2.age; });
After this operation, the scienceClass list will contain the students sorted by ascending age.

The Converter<TInput, TOutput> delegate
This last delegate class is useful when we want to obtain a list of items of type TOutput from a list of items of type TInput. In our case, let's suppose that we want to obtain the list of the names of the students attending our famous natural science course. The TInput type will be the Student class, because we provide a list of students, and the TOutput type will be the string type, because we want in return a list of names. The method of the List<T> collection which is useful in this case is the ConvertAll method, which in fact accepts a Converter delegate:
List<string> names = 
scienceClass.ConvertAll<string>(delegate(Student student)
{
return student.name;
});
Conclusion
At the end of the post you can find a zipped sample console application I've created while writing this post.
As a side note, you must be aware that only the List<T> and Array classes expose methods which accept these delegates as parameters.
I hope this was useful and interesting. That said, for further investigation and for the complete list of methods which accept these delegates I point you to the article (which has lately become an entire chapter on his recent book) by Patrick Smacchia.

kick it on DotNetKicks.com

Attachment: Functors.zip
Posted 20 August 2006 02:22 AM by simoneb | 12 comment(s)
Filed under:
ImageReflection with the Atlas Control Toolkit
A few days ago I blogged about an ASP.NET control I wrote to apply a neat effect to the images of a web form. In the meanwhile I found another implementation of the same effect which is much lighter in the means of both kBytes and cpu work and does exactly the same, so I decided to write another control using this one instead of the script.aculo.us version.

Even I still don't like the Atlas Control Toolkit that much (suffice to say that it doesn't run in medium trust), I chose to try writing this new control using the MS framework. What I like about it is the way it extends the design mode representation of other controls, so that you don't need to create one extender for each of the controls you want to extend, but simply place one extender on the page and then hookup its properties via the wannabe-extended control's properties pane.

Let me tell you that writing an extender with the Atlas Control Toolkit isn't that easy in the starting - and mostly if you are just trying to port and existing script behavior - because you first have to know what the Atlas framework is going to do with your script, and I'm not sure I understand everything is going on behind the scenes yet.
That said, realizing the right way of doing it wasn't much difficult in this case and after some refactorings of the original script I came up with an extender called ImageReflectionExtender, which is built with the latest Atlas and Atlas Control Toolkit releases.

Binaries, source and a screencast are available.

kick it on DotNetKicks.com

LiteBox meets Flickr: LiteBoxFlickrAlbum
Yesterday I got a link on my news aggregator pointing to a new article by Sam Judson on Coding4Fun, which talks about a .NET version of the API for the Flickr services.
A nice idea immediately came to my mind, why not extending the LiteBoxAlbum control to display photos retrieved via Flickr? This way I can have a LiteBox-like photo album which displays photos got from Flickr without writing a single line of code and by setting only a couple of properties, in order to tell the control which photos to look for.

So I wrote a new control derived from LiteBoxAlbum and called LiteBoxFlickrAlbum. They differ in that while the former displays photos placed in the same folder as the page in which the control is added, the other looks for photos on Flickr. It exposes some new properties which are pretty self-descriptive. The only thing to notice is that Flickr lets you use the service only via a Flickr API Key, which it uses for tracking purposes. You'll need to get one in order to use the control, and you can do it at this url. Once you have one, you can take a look at the screencast I recorded.

Watch the screencast!

Source available on the SVN repository (quickstart here) and binary available along with my Script.Aculo.Us.Net library (bottom of the post).

kick it on DotNetKicks.com

ScriptAculoUs.Net on Sourceforge Project Hosting

All my projects are grouped under one main repository located on Sourceforge, together with my main project, BusyBoxDotNet. The source code can be accessed via Subversion.

Here are the links:

QuickStart Guide to SVN

Getting (checking out) the source
  1. Install TortoiseSVN
  2. Create a new folder - preferably in the same directory where you keep your Visual Studio projects - called ScriptAculoUs.Net - or whathever
  3. Right click on the folder just created
  4. Click on "SVN Checkout"
  5. Type "http://busybox.svn.sourceforge.net/svnroot/busybox/trunk" in the textbox "URL of repository"
  6. Click OK. You should have all the source ready to be compiled
Staying up to date with code changes
  1. Right click on the folder where you checked the sources out
  2. Click on "SVN Update"
How do I submit a change I think you may find useful?

In version control jargon, this is called submitting a patch, that is, a small file containing only the changes made to the original code, so that it becomes easy and fast for the project members to review, evaluate and test them, and eventually include them in the code base.

These are the steps to create a patch using TortoiseSVN:
  1. Get the latest version of the source code - important in order not to make changes which may already have been done
  2. Make your changes to the code
  3. Right click on the folder where you checked out the source
  4. On the TortoiseSVN context menu click on "Create Patch..."
  5. Select the files where you have made changes and continue
  6. You are asked to save the file containing the patch, so save it and give it a meaningful name
  7. Contact me and I'll be glad to review your patch!
Scott Hanselman furthermore wrote a more detailed post about creating a patches.

If you're interested in contributing the project or just give feedback or suggestions for future improvements you can even contact me via this link.
LiteBoxAlbum: Autogenerate LightBox-like photo albums
UPDATE 10/08/06: A couple new features, read the bottom of the post for details.

Yesterday I posted about how I created a couple ASP.NET web controls to make it easy to generate a photo gallery using the LiteBox library. Ok now I have to make a confession, that was only a step to achieve something much more useful, an automated LighBox-like image slideshow!

Some time ago I downloaded the very nice PhotoHandler by Bertrand Le Roy, a control/handler which is very versatile and allows you to autogenerate image galleries on the fly, so I thought I would create something similar but instead using the functionality that LiteBox already gives us.

The concept is simple. The control I created is called LiteBoxAlbum, and when you drag it on a web form it automatically searches for images in the same folder of the page itself, and for each of them creates a LiteBoxImageLink and renders it on the page in a hidden fashion, associating each link the same Group (so that you can navigate through them). When you run the page, it simulates a click of the mouse on the first link and starts the slideshow. Now you can navigate through all the images of the folder using the LiteBox interface. That's cool, isn't it?
I recorded a short screencast to show how to use it, even if it's very very simple. It required some black magic to start the slideshow automatically, since the Gecko DOM doesn't allow calling the click method on anchors, so I had to find a workaround which I'm reporting here in case you're interested in the trick:
function simulateClick(elementID) 
{
var el = $(elementID);

if(!document.all)
{
var evt = document.createEvent('MouseEvents');
evt.initMouseEvent('click', true, true, window, 0, 0,
0, 0, 0, false, false, false, false, 0, null);

el.dispatchEvent(evt);
}
else
el.click();
}
UPDATE 10/08/06: By the way, now you can also call the function which starts the album manually. A property called ShowOnLoad lets you choose whether to show it automatically or not. To call the function manually the control exposes a property called StartFunction which returns the Javascript statement to execute in order to start the album. This statement can be triggered, for instance, by an Html input button (the control which triggers it mustn't perform a postback or the album, of course, won't be shown).
Suppose you have placed an Html Input Button called Button1 on your webform, set its runat="server" attribute so that you can retrieve and assign its properties on the server-side.
On The Page_Load event handler you can write the following:
protected void Page_Load(object sender, EventArgs e)
{
Button1.Attributes["onclick"] = LiteBoxAlbum1.StartFunction;
}
Now whenever the button is clicked the album is started.

The screencast can be watched here, while sources and binaries can be downloaded along with my Script.Aculo.Us.Net bundle (bottom of the post).

kick it on DotNetKicks.com

LightBox with ASP.NET
If you don't know what LightBoxes are check out the list at blinklist. Among them two implementantions caught my attention, the original LightBox JS 2.0 by Lokesh Dhakar and the lighter LiteBox by Tyler Mulligan.

The final result is exactly the same, they are able to show images in a really nice fashion, as well as create a slideshow out of them. They differ in some aspects by the way:
  • LightBox JS is based on script.aculo.us and prototype while LiteBox is based on moo.fx and prototype.lite, which are pratically a subset of the original libraries.
  • LightBox JS is heavy since its weight is about 100k, while LiteBox is much lighter, about 30k.
You might be wondering why the effect is exacly the same; well, script.aculo.us and prototype espose a great amount of functionality which LightBox JS doesn't exploit, so there's no need for such heavy libraries. That's why I chose LiteBox for my own port to ASP.NET.

Ok, so we want to get that effect with our images. In order to set LiteBox up you need to:
  • include the scripts into your page
  • import a stylesheet
  • make LiteBox images available in some folder of your website in order for it to be able to retrieve them (I mean the images which show up in the LiteBox to perform navigation and close the box)
  • place your anchors pointing to your images on the page
  • set the rel attribute of your anchor elements to "lightbox"
  • [optional] or set the rel attribute to "lightbox[group]" in order to group together a set of images so that you can surf through them
  • [optional] set the title attribute of the anchors to show a caption for the image.
Ok, too much to do in my opinion. Not very reusable. Let alone that if you want to show thumbnails of the images you have to wrap your anchors around img tags! (ASP.NET HyperLink controls instead expose a property called ImageUrl which does just the same, and it's what I've used for my implementation).

So here comes my wrapper. Nothing to read here the control LiteBoxExtender is obsolete, read on. I created a webcontrol called LiteBoxExtender which includes the scripts and the stylesheet for you, and which will come even more useful later. This control is a non visual control, and works together with another control called LiteBoxImageLink which is wired up automatically to the LiteBoxExtender once dragged on the webform and which represents a link to an image.
The LiteBoxImageLink is derived from HyperLink and behaves the same it does. It only exposes one more property called Group.
So in order to set it up all you have to do is:
  1. Drag on the page as many LiteBoxImageLinks as you want. Each one will represent an image which will show up in the LiteBox.
  2. Set the properties of the LiteBoxImageLink controls:
    • NavigateUrl: the url of the image which will show up in the LiteBox
    • [optional] Text: the text to show in the link to the image
    • [optional] ImageUrl: the url of the preview image (to be used instead of Text)
    • [optional] Group: a group name, in order to group images together and be able to surf through them.

It's that easy, no more scripts and styles to deal with, no images to copy in your website folders, and no manual editing of your anchors to wire up the LiteBox, the controls will do that by themselves. Of course it will work with normal HyperLink controls too as well as with anything that renders on the page as an html anchor tag, but in that case you'll have to follow the manual procedure and set the rel attributes yourself.

The control is available inside my Script.Aculo.Us.Net library.

UPDATE: sources are now only available via the SVN repository. Read here for details. If you download the library you'll find another control called LiteBoxAlbum. I'm not talking about it here since it deserves another post, but it is much cooler than the controls I've described in this post, so you may want to check it out. One advice only, create a blank webform, drag a LiteBox album control in it and place some images (.jpg or .gif) in the same directory as the webform. Then just browse to the page and enjoy!
UPDATE: The follow-up has been posted and is available here.

kick it on DotNetKicks.com

The leading UI suite for ASP.NET - Telerik radControls
Outstanding performance. Full ASP.NET AJAX support. Nearly codeless development.

This site

Search

Go

This Blog

News

     

    CS2
    Checkout CS2, my academic project about indexing and searching personal source code with Lucene.Net.

    Windows Developer Power Tools

Syndication

Sponsors

  • MaximumASP
  • Packet Sniffer
    Home Loan
  • spoc