A short time ago I was confronted with a serious problem. What I needed to do was dynamically choose a UserControl as well as fire methods from that UserControl. The problem lies in the fact that a UserControl does not implement my custom methods that I needed for my controls. Each control was similar and would have the same methods but it would have different display characteristics.
That was when I had a small epiphany. Why can’t I just make an abstract base class? Well the answer is you can! Sometimes I am prone to forget how .NET allows me to customize pre-defined classes. What we can do is create an abstract base class that inherits the UserControl class, then have our UserControls inherit from our base class.
using System; using System.Data; using System.Configuration; using System.Linq; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Xml.Linq;
///<summary> /// Base class to be inherited by a UserControl that displays the date ///</summary> publicabstractclassDateTimeDisplayControl : UserControl { ///<summary> /// Updates the date time inside the user control. ///</summary> publicabstractvoidUpdateDateTime(); }
So in the snippet above, we have created a class called DateTimeDisplayControl. This inherits from UserControl and will have to override the abstract method UpdateDateTime().
Now we can create a couple of UserControls that inherit from our DisplayDateTimeControl class. The first control will be called "ControlOne".
Here is the *.ascx code:
1 2 3 4 5 6 7
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="ControlOne.ascx.cs" Inherits="UserControls_ControlOne" %> <p>User control one</p> <asp:UpdatePanelID="udp1"runat="server"UpdateMode="Conditional"> <ContentTemplate> <asp:LabelID="lblDateTime"runat="server" /> </ContentTemplate> </asp:UpdatePanel>
using System; using System.Collections; using System.Configuration; using System.Data; using System.Linq; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Xml.Linq;
As you can see, ControlOne contains an UpdatePanel with a Label inside of it. The Label will display the date and time. We will call our second control "ControlTwo" and it will look exactly like ControlOne, only it will say "User control two" inside of it.
Now we will create the actual *.aspx page to display the controls.
using System; using System.Configuration; using System.Data; using System.Linq; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Xml.Linq;
privatestring ControlVirtualPath { get { if (string.IsNullOrEmpty(_controlVirtualPath)) _controlVirtualPath = ViewState["ControlVirtualPath"].ToString(); ViewState["ControlVirtualPath"] = _controlVirtualPath; if (string.IsNullOrEmpty(_controlVirtualPath)) thrownew ApplicationException("The control virtual path was not found"); return _controlVirtualPath; } }
private DateTimeDisplayControl LoadedAjaxControl { get { if (_DateTimeDisplayControl == null) { _DateTimeDisplayControl = (DateTimeDisplayControl)Page.LoadControl(ControlVirtualPath); } return _DateTimeDisplayControl; } }
As you may see, the *.aspx page will load up ControlOne by default. There are 3 buttons on the page that will allow you to swap out ControlOne and ControlTwo as well as call the UpdateDateTime() method of the controls.
That is all there is to it! One important note is that I am using a private property to get the loaded control, this is important to note because you will need to call that UpdateDateTime() method on the instance of the control that you rendered to the page. I don’t know why I didn’t think of this long ago, but I hope you will find it as useful as I did!