Introduction
This article shows an example of how we can easily design a web server control that can load or read the ASP.NET Controls
collection. This can be really helpful in a situation where we want to store the user selected values in a form which need to be loaded back automatically when he/she logs back in. The control can work on any number of web controls and in any order. You just have to encompass all the controls that you want to load/store within the template of this control, and that’s it. The best part is that you do not have to configure the control on individual pages on what controls to store or restore, it automatically does that.
Background
Recently, my team had a requirement where the client asked if we can automatically store the search criteria that the user selects on a particular screen under his/her profile, so that the next time they come to the same screen, they do not have to make the same selections. Now, this could have been accomplished by changing the screens to store the search criteria during post back in the database and loading them when the screen is loaded for the first time, from the database, for the user. But, we had around 20-30 such screens, which means lot of code changes, plus this requirement came when we were giving our user acceptance training/testing :) Nice timing, right?
This is when we got the idea of designing this user control, and the outcome was great. Thanks to the user control, all we had to do in those screens was just add the reference to the control and put all the ASP.NET controls within our user control. Just two lines of code change :)
Using the code
I have attached both the server control project and a web project using this control. We’ll go step by step on how to recreate the control on your end.
First, create an ASP.NET server control project. Let’s rename the default class to SmartFilter.vb or whatever you like (we were using it for all our filter controls, so I named it filter). Copy the code from the attachment to your class; you may have to add a reference to System.Design
as it is required by System.Web.UI.Design
.
Compile the code, and add a reference in your web project, and take a look at the sample ASPX page to see how it is used.
Now, let’s see how the code works. Basically, we have designed a template server control so that we can define the contents of the template in the page that is going to use the control. But, the server control will have control on all the controls that are within its template, that’s what gives us the ability to loop through all those controls, and identify them by their type, and then store or restore their values depending on their type. I.e., if the control within the template is a textbox, then we know we will get the value, or can set the value using the Text
property. If the control within the template is a dropdown list, then we know we need to look at the SelectedIndex
property. Similarly, Checked
for radio button and checkbox controls. This way, we can loop through all the controls within a template, determine their type, and take action to store/ restore their values.
Now, as the control was being used by multiple screens, we used two keys to store the values of the user selection, form ID and user ID. This way, when the user goes on a particular screen on the Load
event of the server control, we check whether it’s a post back; if not, we take the user ID and form ID, and retrieve the user’s previous selections from the database. For this example, I am storing and getting them back from the session. You can modify that part to instead go to the database. If it’s a post back, then we take the values from the controls and store them into the session.
Let’s look at the code which is used to store the user's selection in the session. As you can see, all we are doing is loop through all the controls within the template, determining their type, and storing their values in the session.
Similarly, below is the code that loads the control values from the session (or database) when the user comes back to the same form. Again, we are doing the same. First, checking if we have any values in the session for the current form; if we have values, then, we are looping through the array of values and loading them into the control.
Now, let’s take a look at the actual ASPX page that is going to consume this control. All you have to do in that page is give a reference to the server control and encompass all your controls that you want to track within the template of our server control. As you can see, there are bare minimal changes on our ASPX page. Also, there is no code-behind changes for the page; this way, the page that is going to consume the control does not have any logic to store or restore the values of the controls on it.
Points of interest
As you can see from this example, the template control gives us a lot of power, and we can design some really slick functionality for our application. Another advantage is that the actual pages that are going to consume the control are not even aware of the logic on how the saving is accomplished. There is still lot of scope for improvement; for example, we can add a property to our server control to say whether we need the saving ability for a particular user/ page or not. Plus, we can automatically add some common functionality to all the pages. In our case, we automatically added a hide/ show button to all the search criteria so that the user can hide/show the search criteria to save real estate area on the screen. This change was originally not there on any of the pages, but we were able to add it easily as we just had to add it to our server control.