我想创建一个自定义服务器控件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-nest-content-via-markup
不幸的是,一切我都试过了悲惨地失败了。以下是我目前有:
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 documentation for 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。
我希望的功能实际上是(大部分)由内置控件提供的:['MultiView'](http://msdn.microsoft.com/zh-cn/library/system.web.ui .webcontrols.multiview%28V = VS.100%29.aspx)。我甚至不知道这个控制存在!不幸的是,它不允许重用ID [例如'ITemplate'实例](http://stackoverflow.com/a/3671788/346561)。我会继续尝试。 –