HTML-контроль, отображаемый с помощью шаблонных серверных элементов управления CompositeControl
Я создаю свой первый пользовательский серверный элемент управления, который наследуется от CompositeControl
Причиной контроля является возможность иметь согласованную область содержимого (элементы HTML) для нескольких онлайн-приложений, которые мы разрабатываем.
Поэтому вместо того, чтобы постоянно печатать:
<div class="titleBar">
</div>
<div class="actionBar">
</div>
<div class="workspace">
</div>
разработчик может добавить серверный элемент управления следующим образом:
<custom:Workspace id="..." runat="server" Title="MyTitle">
<TitleBar>
Here is the title
</TitleBar>
<ActionBar>
<asp:button id="..." runat="server" Title="MyButton" />
</ActionBar>
<Content>
<asp:DataGrid id="..." runat="server" />
</Content>
</custom:Workspace>
Я прочитал статью на http://msdn.microsoft.com/en-us/library/ms178657.aspx и она работает, но проблема в том... Я не понимаю, почему. (Есть ли у кого-нибудь ссылка на версию статьи непрофессионала, в которой описано, как создавать серверные элементы управления такого типа?)
Главное, что я заметил до сих пор, это то, что Asp.net рендерит кучу элементов SPAN, что, конечно, мне не нужно.
Как можно контролировать HTML, который выводит новый CompositeControl?
Спасибо жак
PS. Вот мой код до сих пор:
using System;
using System.ComponentModel;
using System.Drawing;
using System.Security.Permissions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.Design;
namespace TemplatedServerControl
{
[DefaultProperty("Title")]
[ToolboxData("<{0}:Workspace runat=server></{0}:Workspace>")]
public class Workspace : CompositeControl
{
#region FIELDS
private ITemplate _TitleBarTemplateValue;
private ITemplate _ActionBarTemplateValue;
private TemplateOwner _TitleBarOwnerValue;
private TemplateOwner _ActionBarOwnerValue;
#endregion
#region PROPERTY - TitleBarOwner
[Browsable(false),
DesignerSerializationVisibility(
DesignerSerializationVisibility.Hidden)]
public TemplateOwner TitleBarOwner
{
get
{
return _TitleBarOwnerValue;
}
}
#endregion
#region PROPERTY - ActionBarOwner
[Browsable(false),
DesignerSerializationVisibility(
DesignerSerializationVisibility.Hidden)]
public TemplateOwner ActionBarOwner
{
get
{
return _ActionBarOwnerValue;
}
}
#endregion
#region PROPERTY - Title
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("[Provide the title for the workspace]")]
[Localizable(true)]
public string Title
{
get
{
String s = (String)ViewState["Title"];
return ((s == null) ? "[" + this.ID + "]" : s);
}
set
{
ViewState["Text"] = value;
}
}
#endregion
#region PROPERTY - TitleBar
[Browsable(false),
PersistenceMode(PersistenceMode.InnerProperty),
DefaultValue(typeof(ITemplate), ""),
Description("Control template"),
TemplateContainer(typeof(Workspace))]
public virtual ITemplate TitleBar
{
get
{
return _TitleBarTemplateValue;
}
set
{
_TitleBarTemplateValue = value;
}
}
#endregion
#region PROPERTY - ActionBar
[Browsable(false),
PersistenceMode(PersistenceMode.InnerProperty),
DefaultValue(typeof(ITemplate), ""),
Description("Control template"),
TemplateContainer(typeof(Workspace))]
public virtual ITemplate ActionBar
{
get
{
return _ActionBarTemplateValue;
}
set
{
_ActionBarTemplateValue = value;
}
}
#endregion
#region METHOD - CreateChildControls()
protected override void CreateChildControls()
{
//base.CreateChildControls();
Controls.Clear();
_TitleBarOwnerValue = new TemplateOwner();
_ActionBarOwnerValue = new TemplateOwner();
ITemplate temp1 = _TitleBarTemplateValue;
ITemplate temp2 = _ActionBarTemplateValue;
temp1.InstantiateIn(_TitleBarOwnerValue);
temp2.InstantiateIn(_ActionBarOwnerValue);
this.Controls.Add(_TitleBarOwnerValue);
this.Controls.Add(_ActionBarOwnerValue);
}
#endregion
#region METHOD - RenderContents(HtmlTextWriter writer)
protected override void RenderContents(HtmlTextWriter writer)
{
base.RenderContents(writer);
}
#endregion
}
[ToolboxItem(false)]
public class TemplateOwner : WebControl
{
}
}
2 ответа
Экстра <span>
элементы приходят из TemplateOwner
контролирует, потому что WebControl
(который TemplateOwner
наследует от) оказывает <span>
теги по умолчанию. Вы могли бы изменить TemplateOwner
чтобы указать тег для отображения:
public class TemplateOwner : WebControl
{
public TemplateOwner() :
base(HtmlTextWriterTag.Div)
{
}
}
Но вам не нужно создавать свой собственный класс для использования шаблонов. Например, вы можете просто использовать Panel
управления:
private Panel _TitleBarPanel;
private Panel _ActionBarPanel;
protected override void CreateChildControls()
{
_TitleBarPanel = new Panel { CssClass = "titleBar" };
_TitleBarTemplateValue.InstantiateIn(_TitleBarPanel);
this.Controls.Add(_TitleBarPanel);
_ActionBarPanel = new Panel { CssClass = "actionBar" };
_ActionBarTemplateValue.InstantiateIn(_ActionBarPanel);
this.Controls.Add(_ActionBarPanel);
}
Более простое решение - использовать элемент управления PlaceHolder. Как и CompositeControl, это контейнерный элемент управления. Однако, в отличие от CompositeControl, он вообще не отображает никакой контент - без содержимого или тегов.
Это означает, что вы не можете ссылаться на весь элемент управления программно, как вы можете с помощью CompositeControl, но в зависимости от того, что вы делаете, это может не понадобиться.
Каждый субконтроль будет иметь уникальный идентификатор, поэтому вы можете ссылаться на дочерние элементы управления программно (иметь дело с событиями и т. Д.)