See how to combine two Rendered controls to create a single control that provides the ability to move items both within and between lists.

WEBINAR:

On-Demand

uilding complex Web controls with rich-client interfaces often requires the integration of some client-side JavaScript code with the control's server-side code. While in some cases this does not have to be complicated to achieve some pretty nifty results, it can often break the data synchronization between the control's internal server code and the rendered client HTML code. This becomes a problem when the page posts back. In this article, I will build two very cool Web controls that are vulnerable to this problem and then show you how to fix it.

The controls built in this article are designed for ASP.NET 2.0 for reasons explained later. Later in the article, I will give you a brief workaround explanation for getting them to work in ASP.NET 1.1 (or 1.0).

HTML remains the main language of Web applications at the very end of their rendering cycles. Unfortunately, the protocol that it rides on maintains a characteristic that Web developers have had to deal with known as statelessness. ASP.NET helps to deal with this with awesome architecture characteristics such as the postback mechanism and the ViewState variable. However, for certain functionality, it is still wise to put the extra effort and mix the technologies that lead to your Web page as opposed to constantly hitting the server using postback events. Specifically, I'm talking about using JavaScript and DHTML to access rendered elements on the client side. If you're saying, "Great, we get the best of both worlds," hang on, not so fast. Mixing client and server functionality requires a certain amount of finesse to achieve the nirvana that will contribute to the best user experience. Microsoft itself practices this belief as is demonstrated in the ASP.NET validation controls, which contribute a lot of JavaScript in order to provide a client-side validation experience.

Author's Note: This article assumes a basic knowledge of custom Web control development as explained in "Custom Web Controls Demystified" published in CoDe Magazine Sept/Oct 2005 and Nov/Dec 2005. In the interest of space, I will not repeat basics of Web control development such as how properties work or how styling is added. I strongly encourage that you check out the previous articles and read the Web control tutorial I wrote.

A Conventional Approach
Get ready for a great ride because I'm going to show you how to build a couple of very cool controls with functionality that I have seen in commercial controls you would normally pay good money for. I will continuously demonstrate the benefit of full encapsulation that custom Web controls bring to Web programming. In my last couple of articles I taught you how to hit the ground running developing custom Web controls. One of the concepts I described was encapsulation of all functionality and behavior of a control as you would in a standard business object. This encapsulation will shine when you learn to build controls with complex behavior.

The first control I'll show you how to build is called the EnhancedListBox. This control will extend the ASP.NET ListBox control by adding a heading and some reorder buttons. If you remember my "Custom Web Controls Demystified" articles (CoDe Magazine, Sep/Oct and Nov/Dec 2005) you will recognize this as an inherited control because it will directly inherit from the regular ListBox. Because of this, the control will serve as a drop-in replacement for the ListBox and will give you the ability to optionally display these extra features.

I'll also show you how to build a composite control that will contain two of the above-mentioned EnhancedListBox controls. This control, called ListMover, will also contain some buttons that allow you to move list items from one list to another. You might have seen a control like this in Windows applications and maybe even on Web sites. So you may be asking, "What is the problem?"

Building sites with this type of functionality in ASP.NET is really not that difficult in the conventional method (non-Web control-oriented). First you would drop a regular ListBox control on your Web Form and fill it with some data (in whatever manner you want). Next you would add a label to serve as the heading and a couple of buttons to serve as the reorder buttons. Trapping the server side events for these buttons is standard operating procedure in ASP.NET so all you would need to figure out is a way to take the currently selected item and reposition it higher or lower in the list depending on which button the user clicked. You might write code like this for moving an item up in the list.

Let me analyze what's happening here. First I'm saving the current Index and Item of the selected item in the list. Then I'm removing the item in the current position and reinserting it in a position one index lower. The logic behind his is pretty straightforward, so why am I demonstrating this? Using this conventional method of ASP.NET programming, the reorder buttons on the Web Form raise a server-side event that performs the reordering on the ListBox. This is triggered by a postback to the server and can be a heavy trip depending on what else is on the form as well as the speed of the Internet line.

However, because this code does a standard ASP.NET postback trip, ASP.NET takes care of handling state using its ViewState mechanism. When the page renders back, the contents of the ListBox are rendered correctly and in the order requested.

You can also reproduce this functionality in the ListMover control using the same conventional manner. For the purposes of brevity I won't reproduce it here but you can probably figure out how it goes. The Web Form would contain a couple of ListBoxes along with buttons signifying a move from left-to-right and a move from right-to-left. The server-side events for these buttons would extract the selected item from one ListBox and add it to the other and vice-versa. As in the first example, ViewState would work perfectly here to maintain the items in both of the ListBoxes.