我在互联网上搜索这个,包括这里,现在已经有2天了,但我找不到任何类似的问题。另外,这是我在Stack Overflow上的第一篇文章,请耐心等待:]
这是我第一次真正创建一个模板化服务器控件,但是我在MSDN的帮助下完成了这个模板主题。我已经实现了一个可以像这样使用的控件:
<test:TemplatedControl ID="templatedControl" runat="server">
<Template>
Template start:
<%# Container.EmailText %>
<%# Container.EmailField %>
Template end.
</Template>
</test:TemplatedControl>
控件使用以下容器/上下文作为模板:
public class TemplateContainer : WebControl, INamingContainer
{
public string EmailText
{
get
{
return this.emailLabelText;
}
}
string emailLabelText;
public TextBox EmailField
{
get
{
return this.emailField;
}
}
TextBox emailField;
public TemplateContainer()
: base(HtmlTextWriterTag.Div)
{
this.BorderWidth = 2;
this.BorderStyle = BorderStyle.Outset;
this.emailLabelText = "E-mail:";
this.emailField = new TextBox();
this.emailField.MaxLength = 10;
}
}
容器类的两个属性都可以正常工作,并且在编写模板时可以通过数据绑定表达式访问,但是EmailField正在呈现为System.Web.UI.WebControls.TextBox,这对于给定的代码是可以的。控件的输出是:
<div style="border-width:2px;border-style:Outset;">
Template start:
E-mail:
System.Web.UI.WebControls.TextBox
Template end.
</div>
现在问题是:是否可以通过绑定表达式将控件(如此处的TextBox)作为实际控件输出回模板中作为其他数据?
如果可以,那么就可以选择此控件的输出,包括其子控件,并根据需要通过模板将它们放在一起。
我担心这根本不可能实现,但我想让某人澄清这一点。如果是这样的话,我也愿意接受另一种方法的建议。如果您对我尝试这样做的原因感兴趣,请阅读以下内容。
我正在构建一个复合服务器控件,客户自己将在他的网站上使用,该网站仍在开发中。因此,控件输出的最终布局和格式化需求尚不清楚。相反,控件需要在布局和设计方面具有灵活的输出,因此可以对其进行自定义以便以后匹配该站点。
设计部分可以通过为控件设置一些CSS类属性来实现,尽管为客户配置可能很麻烦,因为控件的输出将非常复杂。
我不确定如何实现可自定义的布局要求,例如,在表结构中呈现表单字段,或者在div中呈现它,或者可能只是内联而不需要额外的HTML等。
因此,我没有提供几种预制类型的输出,而是提出了一个想法,即我的控件呈现的输出可能是模板化的,这可以解决布局和设计灵活性问题。客户会声明性地设置一个模板来包装我的模板需要呈现的东西,这也使他能够根据需要将所有的CSS类设置为包装元素。这引出了上述问题和疑问。
提前致谢,
Garkin
答案 0 :(得分:1)
我认为你需要一个抽象类来定义TemplateContainer
需要具备的内容。例如:
public abstract class TemplateContainer : WebControl, INamingContainer
{
public abstract Literal EmailText { get; }
public abstract TextBox EmailField { get; }
}
然后要求test:TemplateControl
Template
实施TemplateContainer
。
这样您就可以使用EmailText
和EmailField
来应用MaxLength
等。虽然您可能希望在使用之前验证它们不是null
if(EmailText != null)
{
//use EmailText
}
服务器控件的使用者将创建一个与此类似的控件UserTemplate.ascx
:
Template start:
<asp:Literal ID="emailText" runat="server" />
<asp:TextBox ID="emailField" runat="server" />
Template end.
代码落后于UserTemplate.ascx.cs
:
public class UserTemplate : TemplateContainer
{
public Literal EmailText { get { return emailText; } }
public TextBox EmailField { get { return emailField; } }
}
---- ----编辑
根据所有这些,包含test:TemplatedControl
的页面将会是这样的(假设UserTemplate.ascx
的路径别名为test:UserTemplate
):
<test:TemplatedControl ID="templatedControl" runat="server">
<Template>
<test:UserTemplate ID="userTemplate" runat="server" />
</Template>
</test:TemplatedControl>
然后在后面的代码中,您可以访问UserTemplate
上的属性:
templatedControl.Template.EmailText.Text = "Email: ";
templatedControl.Template.EmailField.MaxLength = 10;