Inheriting from a System.Web.UI.UserControl base class
First off, I am wondering if thi开发者_JS百科s is possible. I read slight grumblings around the internet about this, but I was not entirely sure.
My scenario: I have a base chart class which has some methods which all charts should have.
public partial class BaseChart : System.Web.UI.UserControl
{
public BaseChart()
{
}
public void ToggleLegend()
{
Chart1.Legends[0].Enabled = !Chart1.Legends[0].Enabled;
}
}
There is also some mark-up for this BaseChart -- setting background colors, etc. All charts which inherit BaseChart should use this starting mark-up and be able to build upon it.
I would then like to do this:
public partial class HistoricalLineChart : BaseChart
{
public HistoricalLineChart()
: base()
{
}
public HistoricalLineChart(int reportID)
: base()
{
Chart1.Titles[0].Text = "Hello World";
}
}
where HistoricalLineChart is a web user control with no mark-up e.g. "HistoricalLineChart.ascx"
The problem is that Chart1 is undefined when in HistoricalLineChart's scope. Is there something that I am missing here?
Thanks.
Though usually one ends up just making a custom control in this situation (as the other answer suggest), and this is good for many reasons, there are a couple other approaches that may be useful in situations where complicated markup makes a server control infeasible.
1) Create a base class that has all the functionality common to your implementations and inherits UserControl. If you really want to include markup as part of the base class, you could put it in a separate usercontrol with no code, and load it from the abstract class, though this seems a little ugly. If the markup that is shared is simple, though, just render it from code instead.
public abstract class MyUserControl: UserControl
{
public Chart Chart1;
public void ToggleLegend()
{
Chart1.Legends[0].Enabled = !Chart1.Legends[0].Enabled;
}
public override void CreateChildControls()
{
Controls.Add(Page.LoadControl("path/to/mymarkup/control"));
// or add them in code
BuildBaseControls();
}
}
2) Create UserControl implementations that inherit MyUserControl instead of UserControl, and add the markup
public partial class HistoricalLineChart : MyUserControl
{
public HistoricalLineChart(int reportID)
: base()
{
Chart1.Titles[0].Text = "Hello World";
}
}
You could also create an interface that describes any controls that should appear in the markup and implement that. This is nice because it gives you a construct that is applicable to either a UserControl (where the controls are defined in markup) or a WebControl (where the controls are created in code), leaving the actual details of the markup to each implementation, but letting you share the functionality.
Unfortunately the markup portion of BaseChart
is not actually part of the BaseChart
class. The markup is part of a class that gets created when you compile and it inherits from BaseChart
. So HistoricalLineChart
only contains what you've explicitly set in BaseChart
and none of the markup. The only way I know to work around this is to use a Composite Control or Custom Server Control (vs a UserControl).It's a bit more of a pain since you have to add your child controls programmatically, but should do what you want.
Here is an example: http://msdn.microsoft.com/en-us/library/3257x3ea(v=VS.100).aspx
Basically:
- Inherit from
CompositeControl
. - Override
CreateChildControls
. In this method, you can add all of your child controls (like your chart). - Optional: Override
Render
. Override this if you need custom markup in addition to the child controls. You can output your custom markup plus callRenderControl
on all of your child controls to tell them where to render their output. If you don't override this method at all, then the composite control will render out the child controls in the order that they are in the controls collection.
Here are a couple more tutorials:
- http://www.codeproject.com/KB/custom-controls/customdialog.aspx
- http://msdn.microsoft.com/en-us/library/aa479016.aspx
- http://www.codersource.net/asp-net/asp-net-advanced/creating-a-composite-control-in-asp-net.aspx
You can make a protected
property in BaseChart
that exposes the chart.
精彩评论