> Web Forms :: Design Time Support For Custom Templated User Control In VS 2008
> VS 2008 Using the ITemplate in a UserControl and getting a design time rendoring error
> how to show the controls for web user control in design time?
> UserControl ITemplate Property Design Time Error – Easy for a Guru…
但不要再问这个问题:
How do i add templating to a
UserControl
in ASP.net?
到目前为止还没有工作
>从一个新的UserControl5开始,我会调用Contoso:
public partial class Contoso: System.Web.UI.UserControl { }
这将允许我们使用一个新的控件:1
<Contoso> Stuff in here <Contoso>
>创建类型为ITemplate的公共ContentTemplate属性:
public partial class Contoso: System.Web.UI.UserControl { public ITemplate ContentTemplate { get; set; } }
并向ContentTemplate属性添加不确定数量的属性:2
//[ParseChildren(true)] [ParseChildren(true,"ContentTemplate")] //[ParseChildren(false)] public partial class Contoso: System.Web.UI.UserControl { [TemplateContainer(typeof(ContentContainer))] [TemplateInstance(TemplateInstance.Single)] [PersistenceMode(PersistenceMode.InnerProperty)] //[PersistenceMode(PersistenceMode.InnerDefaultProperty)] [Browsable(true)] //[Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] //[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] public ITemplate ContentTemplate { get; set; } }
这将允许我们添加< ContentTemplate>到我们的aspx文件中的控件:1
<Contoso> <ContentTemplate> Stuff in here </ContentTemplate> </Contoso>
>接下来我们需要实际使用ContentTemplate的东西,把它添加到某个地方。我们通过将其添加到我们的UserControl的一个内部div元素中来实现。
从我们原来为空的.aspx文件开始:
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="Contoso.aspx.cs" Inherits="Contoso" %>
我们添加一个将保留ContentTemplate内容的父div:
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="Contoso.aspx.cs" Inherits="Contoso" %> <div id="ContentDiv" runat="server"></div>
然后我们在控件的Init中将ContentTemplate的东西填入父div:
public partial class Contoso: System.Web.UI.UserControl { protected override void OnInit(EventArgs e) { base.OnInit(e); //If there's content,then put it into our ContentDiv div if (this.ContentTemplate != null) this.ContentTemplate.InstantiateIn(ContentDiv); } [PersistenceModeAttribute(PersistenceMode.InnerProperty)] [TemplateInstanceAttribute(TemplateInstance.Single)] [Browsable(true)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public ITemplate ContentTemplate { get; set; } }
>编辑:指示您的类实现INamingContainer
:
public partial class Contoso: System.Web.UI.UserControl: INamingContainer { protected override void OnInit(EventArgs e) { base.OnInit(e); //If there's content,then put it into our ContentDiv div if (this.ContentTemplate != null) this.ContentTemplate.InstantiateIn(ContentDiv); } [PersistenceModeAttribute(PersistenceMode.InnerProperty)] [TemplateInstanceAttribute(TemplateInstance.Single)] [Browsable(true)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public ITemplate ContentTemplate { get; set; } }
INamingContainer
界面没有任何成员,只用于将UserControl类标记为某个东西。
>我们完成了3。现在我们可以在aspx页面中使用这个控件。但是首先我们需要在aspx页面的顶部注册它:
<%@ Register src="Contoso.ascx" TagName="Contoso" tagprefix="uc" %>
哪里:
> Contoso.ascx是ascx文件的名称
> Contoso是我们将用于引用此用户控件的元素的名称
> uc是一些文本,我们将必须放在uc:Contoso(我使用uc作为用户控制的简称)
<uc:Contoso ID="Crackers" runat="server"> <ContentTemplate> Stuff goes here </ContentTemplate> </qwerty:Contoso>
我们完成了!
编辑:忘记添加上述原因不行。 Visual Studio显示错误:
Error Creating Control – Crackers
Type ‘System.Web.UI.UserControl’ does not have a public property named ‘ContentTemplate’
这是有道理的,因为UserControl没有名为ContentTemplate的公共属性 – 所以我很难怪它。
系列
这个问题是正在进行的Stackoverflow系列“模板用户控件”中的一个:
> How to add a Templating to a UserControl?
> How to inherit from Control,rather than UserControl?
> UserControl has IsPostBack,but Control does not
> UserControl does not have public property named ContentTemplate
> How do i specify CodeFileBaseClass from web.config?
奖金阅读
> How to: Create Templated ASP.NET User Controls
> Creating a Templated User Control with ASP.Net 2.0
> Templated User Controls in ASP.NET for Better Maintainability
脚注
> 1你不能使用这种语法。这只是一个容易阅读和理解的形式。
> 2没有人知道要添加什么属性,或为什么。添加或多或少的属性来品味。
> 3未完成完成UserControl,但不是我们的工作。
> 4未完成;它不工作
> 5在网站(不是Web应用程序,不在单独的程序集)
解决方法
BTW。 UserControl不使用Visual Studio Designer呈现,但是当您运行应用程序时,该控件可以正常工作。如果您使用“服务器控件”,则在Visual Studio设计器中正确显示该控件时,这是不同的
以下代码非常适用于构建模板化用户控件和模板化服务器控件,但如果要添加绑定功能,则过程略有不同,take a look
这是创建一个模板的UserControl的代码。
简单输出
模板容器
public class MyTemplateContainer : Control,INamingContainer { }
ASPX代码背后
protected void Page_Load(object sender,EventArgs e) { // just to demonstrate using the contorl this.WebUserControl1.Controls.Add(new LiteralControl("<br />new control")); }
ASPX
<%@ Register src="WebUserControl.ascx" tagname="WebUserControl" tagprefix="uc1" %> <uc1:WebUserControl ID="WebUserControl1" runat="server"> <ContentTemplate> My Template<br /> <asp:Label Text='Hello People' runat="server" ID="lblMessage" /> </ContentTemplate> </uc1:WebUserControl>
ASCX代码落后
public partial class WebUserControl : System.Web.UI.UserControl { [TemplateContainer(typeof(MyTemplateContainer))] [TemplateInstance(TemplateInstance.Single)] [PersistenceMode(PersistenceMode.InnerProperty)] [Browsable(true)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public ITemplate ContentTemplate { get; set; } protected void Page_Init(object sender,EventArgs e) { this.myPlaceHolderTag.Controls.Clear(); if (this.ContentTemplate != null) { var container = new MyTemplateContainer(); this.ContentTemplate.InstantiateIn(container); this.myPlaceHolderTag.Controls.Add(container); } else { this.myPlaceHolderTag.Controls.Add(new LiteralControl("No template defined")); } } }
ASCX
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="WebUserControl.ascx.cs" Inherits="WebUserControl" %> <asp:PlaceHolder runat="server" ID="myPlaceHolderTag" />
产量
ASPX
<%@ Register Namespace="MyControls" TagPrefix="my" %> <my:MyServerControl runat="server" ID="myServerControl"> <ContentTemplate> My Server templated control<br /> <asp:Label Text="My Label" runat="server" /> </ContentTemplate> </my:MyServerControl>
模板容器
namespace MyControls { [ToolBoxItem(false)] public class MyTemplateContainer : Control,INamingContainer { } }
模板服务器控制
namespace MyControls { [ToolBoxData("<{0}:MyServerControl runat=server >")] [ToolBoxItem(true)] [ParseChildren(true)] // you can inherit from another control if you like,for example from the CompositeControl public class MyServerControl : Control,INamingContainer { [TemplateInstance(TemplateInstance.Multiple)] [TemplateContainer(typeof(MyTemplateContainer))] [PersistenceMode(PersistenceMode.InnerProperty)] [Browsable(true)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] [DefaultValue(null)] public ITemplate ContentTemplate { get; set; } protected override void CreateChildControls() { var p = new Panel { ID = "myPanel",BackColor = Color.Silver,Width = new Unit("100%") }; if (this.ContentTemplate == null) { p.Controls.Add(new LiteralControl("No content has been specified")); } else { var c = new MyTemplateContainer(); this.ContentTemplate.InstantiateIn(c); p.Controls.Add(c); } this.Controls.Clear(); this.Controls.Add(p); } public override void DataBind() { this.CreateChildControls(); this.ChildControlsCreated = true; base.DataBind(); } public override ControlCollection Controls { get { this.EnsureChildControls(); return base.Controls; } } } }
参考文献:
> How to: Create Templated ASP.NET User Controls
> Building Templated Custom ASP.NET Server Controls
> Building DataBound Templated Custom ASP.NET Server Controls