Мне нужен главный пользовательский элемент управления (главная страница, но для пользовательских элементов управления)

Главные страницы ASP.NET — важные вещи.

Однако в моих проектах есть много очень похожих пользовательских элементов управления — это может быть стандартный макет для AJAX ModalPopup или что-то более сложное.

Я хотел бы избавиться от части моего дублированного кода (как в файлах ascx, так и в коде программной части) с помощью некоторых основных пользовательских элементов управления.

Есть ли у кого-нибудь предложения о том, как этого добиться?


person Richard Ev    schedule 02.12.2008    source источник


Ответы (5)


Самое близкое, что я могу предложить для того, что вы ищете, это шаблон пользовательского элемента управления. К сожалению, совместное использование элементов управления в проектах намного проще, если это настраиваемые элементы управления без файла ascx.

person Chris Shaffer    schedule 03.12.2008

это старый вопрос, но у меня есть надежное решение для всех, кто наткнется на это.

в app_code создайте файл и вставьте этот код:

namespace MasterControls
{
    // code written by alexander taylor on 2011-08-22. http://www.alexsapps.com

    public abstract class ChildUserControl : UserControl
    {
        Control master;

        public abstract string MasterControlVirtualPath { get; }

        protected override void OnInit(EventArgs e)
        {
            master = LoadControl(MasterControlVirtualPath);
            Controls.Add(master);

            base.OnInit(e);
        }

        protected override void Render(HtmlTextWriter writer)
        {
            master.RenderControl(writer);
        }
    }
    public class ControlContentPlaceHolder : Control
    {
        protected override void Render(HtmlTextWriter writer)
        {
            ControlContent found = null;

            foreach (Control c in NamingContainer.NamingContainer.Controls)
            {
                ControlContent search;
                search = c as ControlContent;
                if (search != null && search.ControlContentPlaceHolderID.Equals(ID))
                {
                    found = search;
                    break;
                }
            }

            if (found != null)
            {                
                //write content of the ContentControl
                found.RenderControl(writer);
            }
            else
            {
                //use default content
                base.Render(writer);
            }
        }
    }
    public class ControlContent : Control
    {
        public string ControlContentPlaceHolderID { get; set; }
    }

}

пример "главный элемент управления" (эквивалент мастер-страницы)

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="MasterControl1.ascx.cs" Inherits="MasterControl1" %>
<%@ Register Namespace="MasterControls" TagPrefix="masterControls" %>

<p>content 1 below:<br />
<masterControls:ControlContentPlaceHolder ID="myContent1" runat="server">
    default content 1 here!
</masterControls:ControlContentPlaceHolder></p>

<p>content 2 below:<br />
<masterControls:ControlContentPlaceHolder ID="myContent2" runat="server">
    default content 2 here!
</masterControls:ControlContentPlaceHolder></p>

пример "детский контроль" (эквивалент страницы)

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="ChildControl1.ascx.cs" Inherits="Control1" %>
<%@ Register Namespace="MasterControls" TagPrefix="masterControls" %>

<masterControls:ControlContent ControlContentPlaceHolderID="myContent1" runat="server">
    custom content 1
</masterControls:ControlContent>

<masterControls:ControlContent ControlContentPlaceHolderID="myContent2" runat="server">
    custom content 2
</masterControls:ControlContent>

в коде дочернего элемента управления

using MasterControls;

//you must inherit the ChildUserControl class!
public partial class Control1 : ChildUserControl
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    public override string MasterControlVirtualPath
    {
        //below, type the location to the master control
        //you wish to apply to this control
        get { return "~/MasterControl1.ascx"; }
    }
}
person Alexander Taylor    schedule 23.08.2011

Мне удалось заставить это работать, используя следующий код:

public class MasterLoader : UserControl
{
    MasterUserControl _masterUserControl;

    protected override void CreateChildControls()
    {
        Controls.Clear();
        base.CreateChildControls();

        Controls.Add(MasterControl);
    }

    protected override void AddedControl(Control control, int index)
    {
        if (control is MasterUserControl)
            base.AddedControl(control, index);
        else
            MasterControl.ContentArea.Controls.Add(control);
    }

    private MasterUserControl MasterControl
    {
        get
        {
            if (_masterUserControl== null)
                _masterUserControl= (MasterUserControl)LoadControl("~/MasterUserControl.ascx");

            return _masterUserControl;
        }
    }
}

Дочерние пользовательские элементы управления наследуются от класса MasterLoader. Главный пользовательский элемент управления включал в себя элемент управления-заполнитель, который я представил как общедоступное свойство с именем ContentArea.

public partial class MasterUserControl: UserControl
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    public PlaceHolder ContentArea 
    {
        get
        {
            return phContent;
        }
    }
}

Привязка событий и состояние представления работают должным образом без каких-либо изменений в каких-либо пользовательских элементах управления.

person Mike    schedule 07.10.2010

Наследование. Вы создаете базовый элемент управления как базовый класс, а затем наследуете от него.

person Joel Coehoorn    schedule 02.12.2008
comment
Я сделал это для кода программной части (т. е. мой файл UserControl.ascx.cs наследуется от моего BaseUserControl, а не от System.Web.UI.UserControl. Однако это помогает мне с точки зрения добавления стандартных HTML и серверных элементов управления к моему базовому контролю. - person Richard Ev; 02.12.2008

Вы также можете поместить вложенный пользовательский элемент управления в элемент управления-заполнитель в «главном» пользовательском элементе управления. Используйте метод Load, который принимает виртуальный путь к файлу ascx для загрузки соответствующего элемента управления.

person Aleksandar    schedule 02.12.2008