views:

328

answers:

3

I have a UserControl that is working fine. It is declared like this.

public partial class DynamicList : System.Web.UI.UserControl
{
        protected static BaseListController m_GenericListController = null;

        public DynamicList()
        {
            m_GenericListController = new GenericListController(this);
        }
}

Now I want to override this control so I can change some of the properties. I have created a class like this.

public partial class JobRunningList : DynamicList
{
    public JobRunningList()
    {
        m_GenericListController = new JobListController(this);
        (m_GenericListController as GenericListController).ModuleId = 14;
    }
}

It appears that the controls in the DynamicList are not getting created though when I use the JobRunningList control now causing predictably bad results. The DynamicList UserControl has a ListView on it and a few other controls. It appears these are not created when using the JobRunningList. Is there any secret to this?

A: 

The boring workaround would be to make JobRunningList as plain old user control that contains a DynamicList and just sets the properties of the inner control in its OnLoad. That's awkward if DynamicList has many other properties that you want to access from the page though, as JobRunningList would have to define matching properties of its own. Getting back to the inheritance approach, then...

The DynamicList class just contains the code behind logic, so what you're doing works nicely if you want the second control to reuse the logic behind the first but provide a new UI of its own.

The markup in your .ascx file gets compiled into another class that inherits DynamicList, so if you can get your JobRunningList class to inherit that class instead of DynamicList, you'll get the result you want. This class gets a default name derived from the filename, but you can avoid guessing that by setting a ClassName in the control directive to use instead of the automatic name.

Take a simple base control like

<%@ Control Language="C#" AutoEventWireup="true"
            CodeFile="HelloControl.ascx.cs" Inherits="HelloControlBase"
            ClassName="MyControls.HelloControl" %>

Hello <%= Name %>

with an unexciting code-behind like

public partial class HelloControlBase : System.Web.UI.UserControl
{
    public string Name
    {
       get;
       set;
   }
}

Now we want to override the Name property in a new control. First we need HelloAlice.ascx

<%@ Control Language="C#" AutoEventWireup="true"
            CodeFile="HelloAliceControl.ascx.cs"
            Inherits="HelloAliceControl" %>

Not much to see here, since we're leaving all the work to the original ascx. Now in the code-behind,

public partial class HelloAliceControl : MyControls.HelloControl
{
    protected void Page_Load(object sender, EventArgs e)
    {
        this.Name = "Alice";
    }
}

We just inherit MyControls.HelloControl and set the Name property, and it looks like we're done.

The problem is knowing when MyControls.HelloControl is visible. As long as your derived control is in the same directory as the parent control you'll probably be OK, otherwise it's quite easy to run into build errors complaining that the class doesn't exist because the parent control hasn't been compiled yet.

stevemegson
A: 

If I understand correctly, you want the interface to be the same. In that case, I would create some properties instead. Perhaps just a simple enumeration i.e. ListType.

eglasius
A: 

I tries the same codes here however webuser control HelloAliceControl cannot extend to MyControls.HelloControl right here HelloAliceControl : MyControls.HelloControl .NET don't recognizes MyControls.HelloControl of webusercontrol HelloControlBase. They( HelloControlBase and HelloAliceControl) are in the same directory of my webapp. Right in the base directory of my webapp. How can i succeed that?