Reusing web user controls
“Why”?
With this post I want to demonstrate how to reuse Web User Controls in multiple web projects to avoid the duplication of code and interface. How many times many of us needed a Web User Control created in another web project, and use it directly in the project you are working on? The first temptation is to copy the user control to the new web project, but then your conscience is shouting inside you “you should not be doing that”, you try to ignore and it fades, and then you find a bug or make that control a tiny bit better and you have to do it as many times as you have made a copy, then it returns (the conscience) saying “you should not have done that” J.
The user control library
To start with, let us create a Web User Control Library. To do this we create a new project in Visual Studio using ASP.NET WebApplication and named it MyUserControlLibrary like the image below and then click OK:
The next step is to delete from the project MyUserControlLibrary the files Default.aspx and Web.config, we won´t be needingthem in this project.
Next we add to the project a new Web User Control, name it MyReusableUserControl.ascx and click the Add button.
In this example this user control is going to be a text field validated to only allow numbers between 1 and 200 and has a label whose text we can change. To do this we create a public property whose name is Caption.
public string Caption { get { return lblCaption.Text; } set { lblCaption.Text = value; }
} |
And the reusable user control is ready.
Prepare to use the MyUserControlLibrary
To use the user control we will need to add a new ASP.NET WebApplication to the solution and name it
MyTestWebApplication, then add to MyTestWebApplication a new Web User Control and call it MyTestWebUserControl.ascx. We will also add to MyTestWebApplication a folder with the name UserControls for future use . The final solution layout should look like the image below.
There are several ways to reuse the user control library in other projects, like managing the user control library in a different solution or use the project library in the same solution you are working, in this case we go with the second choice.
Within MyTestWebApplication we add a reference to the User Control Library project. To do that we right click on the references node and click Add reference –> Projects, select the project MyUserControlLibrary and then click OK.
Now right click on MyTestWebApplication and select Properties and then the Build Events Tab. Here we will do the pre-build event command for this project. The command will copy the *.ascx from the MyUserControlLibrary to the local UserControls folder created earlier, remember. This way the .ascx files will be accessible to be used in the project, but will not be added to the project itself, this way they can be easily excluded from the source control of the project and always updated. The command should look like this:
copy $(SolutionDir)\MyUserControlLibrary\*.ascx$(ProjectDir)\UserControls\
Another way to do this is to use MSBUILD to do the job. For this you have to edit the Project file MyTestWebApplication.csproj in notepad for example which is a XML file. Once the file is opened you should look for the fallowing commented area.
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets. <Target Name="BeforeBuild"> </Target> <Target Name="AfterBuild"> </Target> --> |
In this case we want to use the BeforeBuild target and we want to add a MSBuild task inside this target to copy the .ascx files inside our UserControls directory. To do this we are creating a new ItemGroup, defining from where and what files are we going to copy. The best way is to find the last < /ItemGroup> tag and add the following next below it.
<ItemGroup> <MyCustomReusableASCX Include="$(SolutionDir)\MyUserControlLibrary\*.ascx" /> </ItemGroup> |
Next we add the copy task to the before build Target just like this.
<Target Name="BeforeBuild"> <Copy SourceFiles="@(MyCustomReusableASCX)" DestinationFolder="@(MyCustomReusableASCX->'$(ProjectDir)\UserControls\')" /> </Target> |
Save the file and MSBuild as everything he needs to copy the .ascx to the UserControls folder.
This will have exactly the same effect as the copy command on the pre-build event command but using the MSBuild, but this was a chance to show you a tiny bit of MSBuild J.
At the moment what we have to do is to build the solution and if everything goes right, we will have no errors, and the MyUserControlLibrary.ascx will be waiting to be used inside of the UserControls Folder in the Web Application. To be able to see the user control we have to select the MyTestWebApplication project and activate the option Show All Files on the top of the Solution Explorer. The Solution Explorer should look like the image below.
MyTestWebUserControl
We could use MyReusableUserControl.ascx directly on Default.aspx but instead we will use MyTestWebUserControl.ascx to embed MyReusableUserControl.ascx, and then use MyTestWebUserControl.ascx, that is the combination of both in the Default.aspx page.
This user control will have two labels and two text boxes (Fist Name, Last Name) and our custom user control (MyReusableUserControl.ascx) that will accept only as an input, a number between 1 and 200 . The aspect of MyTestWebUserControl.ascx lookslike this:
Notice that the MyReusableUserControl.ascx appears highlighted. To use this user control in MyTestWebUserControl.ascx we simply dragged the user control from the folder UserControls to the MyTestWebUserControl.ascx design view. In Visual Studio 2005 and 2008 user controls are supported in WISIWYG (What I See Is What You Get) so it´s possible to see the controls rendered in the design view instead of the grey box in Visual Studio 2003.
Putting it all together
We will use the page Default.aspx to put our example together. To do this we simply drag MyTestWebUserControl.ascx tothe Default.aspx design view, and our interface is almost ready. The next step is to use the final user control in Default.aspx. We also added a BulletedList to the page and a Button.
And then add the following code to the OnClick event of the Submit Button:
protected void btSubmit_Click(object sender, EventArgs e) { BulletedList1.Items.Clear(); if (Page.IsValid ) { BulletedList1.Items.Add(((TextBox)MyTestWebUserControl1.FindControl("txtFirstName")).Text); BulletedList1.Items.Add(((TextBox)MyTestWebUserControl1.FindControl("txtLastName")).Text); MyUserControlLibrary.MyReusableUserControl uc = (MyUserControlLibrary.MyReusableUserControl)MyTestWebUserControl1.FindControl("MyReusableUserControl1"); BulletedList1.Items.Add(((TextBox)uc.FindControl("txtNumber")).Text); } } |
The final Result is:
Just to be easier to understand, below is an image with the parts which the final page is built with.
Voilá! And the example is complete. Reuse your code and I promise you, your conscience will leave you aloneJ.
See you next time!
ReuseWebUserControlsSample.zip
Comments
Anonymous
March 23, 2010
impressive post. thanks a lot very helpful and useable post. many many thanks to you again. request to you to post such a useable thing, highly appreciation.Anonymous
May 07, 2010
The comment has been removedAnonymous
May 25, 2010
Great post! But would we need to rebuild everything for a change in the User control????Anonymous
May 25, 2010
Great Post! Would we need to re-build all projects if the user control changes?Anonymous
May 27, 2010
The procedure is not different from changing another project, if you current project depends on that project you need to rebuild you project to reflect the changes. So in this case when you build the project that uses the user control, the .ascx is copied to the project User Controls folder on the project.Anonymous
February 01, 2011
copy $(SolutionDir)MyUserControlLibrary*.ascx $(ProjectDir)UserControls