我想创建一个自定义服务器控件,VersionedContentControl
它允许我指定最终标记的不同变体。
示例用法:
<custom:VersionedContentControl runat="server" VersionToUse="2">
<ContentVersions>
<Content Version="1">
<asp:HyperLink runat="server" ID="HomeLink" NavigateUrl="~/Default.aspx">Home</asp:HyperLink>
</Content>
<Content Version="2">
<asp:LinkButton runat="server" ID="HomeLink" OnClick="GoHome">Home</asp:LinkButton>
</Content>
<Content Version="3">
<custom:HomeLink runat="server" ID="HomeLink" />
</Content>
</ContentVersions>
</custom:VersionedContentControl>
使用上面的标记,我希望LinkButton
在页面上使用唯一的控件。
很长的故事
我在尝试定义这个自定义控件时遇到了很大的困难。我什至无法在 MSDN 上找到使用这样的嵌套控件的好例子。相反,我不得不求助于以下这些博客文章作为示例:
- http://blog.spontaneouspublicity.com/child-collections-in-asp-net-custom-controls
- http://www.tomot.de/en-us/article/2/asp.net/how-to-create-an-asp.net-control-that-behaves-as-a-template-container-to-通过标记嵌套内容
不幸的是,我所尝试的一切都惨遭失败。这是我目前拥有的:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.UI;
namespace CustomControls
{
[ParseChildren(true)]
[PersistChildren(false)]
public class VersionedContentControl : Control, INamingContainer
{
public string VersionToUse { get; set; }
[PersistenceMode(PersistenceMode.InnerProperty)]
public IList<Content> ContentVersions { get; set; }
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
var controlToUse = ContentVersions.Single(x => x.Version == VersionToUse);
Controls.Clear();
controlToUse.InstantiateIn(this);
}
}
public class Content : ITemplate
{
public string Version { get; set; }
public void InstantiateIn(Control container)
{
// I don't know what this method should do
}
}
public class ContentVersionsList : List<Content> {}
}
即使我还没有实现InstantiateIn
,我的内容的所有 3 个版本都出现在页面上;它显示了 3 个链接。
ID
此外,除非我为每个嵌套控件指定不同的属性值,否则我实际上无法使用该控件;我不能"HomeLink"
全部使用。我希望能够重新使用,ID
以便我可以从后面的代码中访问控件。
我意识到,通常情况下,禁止为ID
页面上的多个控件指定重复值。但是,在MSDN 文档中System.Web.UI.MobileControls.DeviceSpecific
,示例ID
对嵌套控件使用重复值。事实上,这个例子非常接近我想要做的;它根据移动设备兼容性过滤器区分内容。
<mobile:Form id="Form1" runat="server">
<mobile:DeviceSpecific Runat="server">
<Choice Filter="isHTML32">
<HeaderTemplate>
<mobile:Label ID="Label1" Runat="server">
Header Template - HTML32</mobile:Label>
<mobile:Command Runat="server">
Submit</mobile:Command>
</HeaderTemplate>
<FooterTemplate>
<mobile:Label ID="Label2" Runat="server">
Footer Template</mobile:Label>
</FooterTemplate>
</Choice>
<Choice>
<HeaderTemplate>
<mobile:Label ID="Label1" Runat="server">
Header Template - Default</mobile:Label>
<mobile:Command ID="Command1" Runat="server">
Submit</mobile:Command>
</HeaderTemplate>
<FooterTemplate>
<mobile:Label ID="Label2" Runat="server">
Footer Template</mobile:Label>
</FooterTemplate>
</Choice>
</mobile:DeviceSpecific>
</mobile:Form>
看看这些控件的源代码以了解它们是如何实现这一点的,但不幸的是,它不是开源的。
我的问题
如何创建包含嵌套控件列表并仅基于属性呈现嵌套控件之一的自定义服务器控件?理想情况下,在单独的嵌套控件中重复使用 ID。