Хотя обычно получается, что в этой ситуации создается пользовательский элемент управления (как предполагает другой ответ), и это хорошо по многим причинам, есть пара других подходов, которые могут быть полезны в ситуациях, когда сложная разметка делает сервер управление неосуществимо.
1) Создайте базовый класс, который имеет все функциональные возможности, общие для ваших реализаций, и наследует UserControl. Если вы действительно хотите включить разметку как часть базового класса, вы можете поместить ее в отдельный пользовательский контроль без кода и загрузить ее из абстрактного класса, хотя это выглядит немного уродливо. Если общая разметка проста, просто вместо этого визуализируйте ее из кода.
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) Создайте реализации UserControl, которые наследуют MyUserControl вместо UserControl, и добавьте разметку
public partial class HistoricalLineChart : MyUserControl
{
public HistoricalLineChart(int reportID)
: base()
{
Chart1.Titles[0].Text = "Hello World";
}
}
Вы также можете создать интерфейс, который описывает любые элементы управления, которые должны появиться в разметке, и реализовать это. Это хорошо, потому что дает вам конструкцию, которая применима либо к UserControl (где элементы управления определены в разметке), либо к WebControl (где элементы управления создаются в коде), оставляя фактические детали разметки для каждой реализации, но позволяя вам поделиться функциональностью.