如何将模板添加到用户控件? [英] How to add a Templating to a UserControl?
问题描述
这个问题已经被问过
- Web窗体::设计时支持自定义模板化用户控制在VS 2008
- VS 2008的用户控件使用的ITemplate和获取设计时rendoring误差
- how显示在设计时为Web用户控件的控件?
- 用户控件的ITemplate属性设计时错误 - 简易的大师......
但它不会伤害再次问它:
我如何在ASP.net模板添加到
用户控件
?
块引用>什么至今还没有制定
开始一个新的
用户控件
5 ,我称之为的Contoso
:公共部分类Contoso的:System.Web.UI.UserControl
{
}这将允许我们使用一个新的控件: 1
<&Contoso的GT;
东西在这里
<&Contoso的GT;
创建一个公共
的ContentTemplate
属性类型了Itemplate
:公共部分类Contoso的:System.Web.UI.UserControl
{
公开了Itemplate的ContentTemplate {搞定;组; }
}和属性添加到
的ContentTemplate
属性的一个不确定数: 2// [ParseChildren(真)]
[ParseChildren(真的ContentTemplate)]
// [ParseChildren(假)]
公共部分类Contoso的:System.Web.UI.UserControl
{
[TemplateContainer(typeof运算(ContentContainer))]
[模板实例(TemplateInstance.Single)
[PersistenceMode(PersistenceMode.InnerProperty)
//[PersistenceMode(PersistenceMode.InnerDefaultProperty)
[可浏览(真)]
// [可浏览(假)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)
//[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)
公开了Itemplate的ContentTemplate {搞定;组; }
}这将允许我们添加
<&的ContentTemplate GT;
在我们的aspx文件控制: 1<&Contoso的GT;
<&的ContentTemplate GT;
东西在这里
< /&的ContentTemplate GT;
< / Contoso的>
接下来,我们需要真正的使用的的
的ContentTemplate
的东西,由地方添加它。我们将它添加到我们的用户控件的内部DIV
元素之一做到这一点。这原本是空的我们的
的.aspx
文件启动:<%@控制语言=C#AutoEventWireup =真codeFILE =Contoso.aspx.cs继承=Contoso的%>
我们添加一个父
DIV
,将持有我们的的ContentTemplate
的东西:<%@控制语言=C#AutoEventWireup =真codeFILE =Contoso.aspx.cs继承=Contoso的%>
< DIV ID =ContentDiv=服务器>< / DIV>然后,我们的东西在
的ContentTemplate
的东西成父DIV
在控制的初始化公共部分类Contoso的:System.Web.UI.UserControl
{
保护覆盖无效的OnInit(EventArgs的发送)
{
base.OnInit(E); //如果有内容,然后把它放到我们的ContentDiv DIV
如果(this.ContentTemplate!= NULL)
this.ContentTemplate.InstantiateIn(ContentDiv);
} [PersistenceModeAttribute(PersistenceMode.InnerProperty)
[TemplateInstanceAttribute(TemplateInstance.Single)
[可浏览(真)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)
公开了Itemplate的ContentTemplate {搞定;组; }
}
修改:表明你的类所实现的
作INamingContainer
:公共部分类的Contoso:System.Web.UI.UserControl:作INamingContainer
{
保护覆盖无效的OnInit(EventArgs的发送)
{
base.OnInit(E); //如果有内容,然后把它放到我们的ContentDiv DIV
如果(this.ContentTemplate!= NULL)
this.ContentTemplate.InstantiateIn(ContentDiv);
} [PersistenceModeAttribute(PersistenceMode.InnerProperty)
[TemplateInstanceAttribute(TemplateInstance.Single)
[可浏览(真)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)
公开了Itemplate的ContentTemplate {搞定;组; }
}
作INamingContainer
接口没有任何成员,只用来标记你的用户控件
类的东西。和我们完成了 3 。现在,我们可以用我们的aspx页面此控件。但首先,我们需要的注册它在我们的aspx页面的顶部:
<%@注册SRC =Contoso.ascx变量名=Contoso的标签preFIX =UC%GT;
其中:
Contoso.ascx
是ASCX的名称
文件的Contoso
是元素的名称,我们将用引用这个用户的控制UC
有点文字,我们将不得不把在前UC:Contoso的
(我用UC
短的的用户控件的)控件添加到我们的页面:
< UC:Contoso的ID =饼干=服务器>
<&的ContentTemplate GT;
东西放在这里
< /&的ContentTemplate GT;
< / QWERTY:Contoso的>
和我们就大功告成了! 4
修改:忘了补充上述不工作的原因。 Visual Studio中显示了错误:
错误创建控制 - 饼干
键入System.Web.UI.UserControl'没有名为'的ContentTemplate的公共属性。
块引用>
这是有道理的,因为
用户控件
没有命名的公共属性的ContentTemplate
- 所以我也很难责怪系列
这个问题是一个在正在进行的系列#1,模板的用户控件
- How一个模板添加到用户控件?
- How从控制继承,而不是用户控件?
- UserControl拥有的IsPostBack,但控制不
- UserControl不具有公共属性命名的ContentTemplate
- How我该从web.config中指定codeFileBaseClass?
奖金阅读
脚注
- 1 你永远不能使用该语法。这只是一个简单的阅读和理解的形式。
- 2 没有人知道什么属性添加,或者为什么。添加更多或更少属性的味道。
- 3 没有这样做。完成与用户控件,但不是我们的工作。
- 4 未完成;这是行不通的。
- 5 的网站(而不是一个Web应用程序,而不是在一个单独的程序)
解决方案好吧,我相信你几乎得到了它。
BTW。该用户控件使用Visual Studio设计不渲染,但是当你运行应用程序的控制工程。如果你使用服务器控件来代替,在这种情况下,正确地在Visual Studio设计显示的控制,这是不同的。
以下code的伟大工程打造的模板化用户控件和模板化服务器控件然而,如果你想添加的绑定功能,这个过程略有不同,的看一看
这是code创建一个模板
用户控件
。简单输出
模板Container
公共类MyTemplateContainer:控制,作INamingContainer {}
ASPX $ C $后面
ç保护无效的Page_Load(对象发件人,EventArgs的发送)
{
//只是为了演示使用contorl
this.WebUserControl1.Controls.Add(新LiteralControl(< BR />新建控制));
}ASPX
<%@注册SRC =WebUserControl.ascx变量名=WebUserControl标签preFIX =UC1%GT; < UC1:WebUserControl ID =WebUserControl1=服务器>
<&的ContentTemplate GT;
我的模板< BR />
< ASP:标签文本='你好的人=服务器ID =lblMessage/>
< /&的ContentTemplate GT;
< / UC1:WebUserControl>ASCX $ C $后面
ç公共部分类WebUserControl:System.Web.UI.UserControl
{
[TemplateContainer(typeof运算(MyTemplateContainer))]
[模板实例(TemplateInstance.Single)
[PersistenceMode(PersistenceMode.InnerProperty)
[可浏览(真)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)
公开了Itemplate的ContentTemplate {搞定;组; } 保护无效Page_Init(对象发件人,EventArgs的发送)
{
this.myPlaceHolderTag.Controls.Clear(); 如果(this.ContentTemplate!= NULL)
{
VAR集装箱=新MyTemplateContainer(); this.ContentTemplate.InstantiateIn(容器);
this.myPlaceHolderTag.Controls.Add(容器);
}
其他
{
this.myPlaceHolderTag.Controls.Add(新LiteralControl()没有定义的模板);
}
}
}ASCX
<%@控制语言=C#AutoEventWireup =真codeFILE =WebUserControl.ascx.cs继承=WebUserControl%GT;< ASP:占位符=服务器ID =myPlaceHolderTag/>
code以添加一个模板化服务器控件
输出
ASPX
<%@注册的命名空间=MyControls标签preFIX =我的%GT;<我:MyServerControl =服务器ID =myServerControl>
<&的ContentTemplate GT;
我的服务器模板控制< BR />
< ASP:标签文本=我的标签=服务器/>
< /&的ContentTemplate GT;
< /我:MyServerControl>模板Container
命名空间MyControls
{
[的ToolboxItem(假)]
公共类MyTemplateContainer:控制,作INamingContainer {}
}模板化服务器控件
命名空间MyControls
{
[ToolboxData(< {0}:MyServerControl RUNAT =服务器>中)
[的ToolboxItem(真)
[ParseChildren(真)
//你可以从另一个控制,如果你喜欢继承,例如从CompositeControl的
公共类MyServerControl:控制,作INamingContainer
{
[模板实例(TemplateInstance.Multiple)
[TemplateContainer(typeof运算(MyTemplateContainer))]
[PersistenceMode(PersistenceMode.InnerProperty)
[可浏览(真)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)
[默认值(NULL)
公开了Itemplate的ContentTemplate {搞定;组; } 保护覆盖无效的CreateChildControls()
{
变种p值=新面板{ID =myPanel,背景色= Color.Silver,宽度=新的单位(100%)}; 如果(this.ContentTemplate == NULL)
{
p.Controls.Add(新LiteralControl(没有内容已经被指定));
}
其他
{
变种C =新MyTemplateContainer(); this.ContentTemplate.InstantiateIn(C);
p.Controls.Add(C);
} this.Controls.Clear();
this.Controls.Add(P);
} 公共覆盖无效的DataBind()
{
this.CreateChildControls();
this.ChildControlsCreated = TRUE;
base.DataBind();
} 公众覆盖的ControlCollection控制
{
得到
{
this.EnsureChildControls();
返回base.Controls;
}
}
}
}参考文献:
This question has been asked before
- 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...
but it doesn't hurt to ask it again:
How do i add templating to a
UserControl
in ASP.net?
What hasn't worked so far
Start with a new
UserControl
5, which i'll callContoso
:public partial class Contoso: System.Web.UI.UserControl { }
This will allow us to use a new control:1
<Contoso> Stuff in here <Contoso>
Create a public
ContentTemplate
property of typeITemplate
:public partial class Contoso: System.Web.UI.UserControl { public ITemplate ContentTemplate { get; set; } }
and add an indeterminate number of attributes to the
ContentTemplate
property: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; } }
this will allow us to add
<ContentTemplate>
to the control in our aspx file:1<Contoso> <ContentTemplate> Stuff in here </ContentTemplate> </Contoso>
Next we need to actually use the
ContentTemplate
stuff, by adding it somewhere. We do this by adding it to one of our UserControl's internaldiv
elements.Starting from our
.aspx
file which was originally empty:<%@ Control Language="C#" AutoEventWireup="true" CodeFile="Contoso.aspx.cs" Inherits="Contoso" %>
we add a parent
div
that will hold ourContentTemplate
stuff:<%@ Control Language="C#" AutoEventWireup="true" CodeFile="Contoso.aspx.cs" Inherits="Contoso" %> <div id="ContentDiv" runat="server"></div>
Then we stuff the
ContentTemplate
stuff into that parentdiv
during the control's Init: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; } }
Edit: Indicate that your class implements
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; } }
The
INamingContainer
interface does not have any members, and is only used to mark yourUserControl
class as something.And we're done3. We can now use this control in our aspx page. But first we need to "register" it at the top of our aspx page:
<%@ Register src="Contoso.ascx" TagName="Contoso" tagprefix="uc" %>
Where:
Contoso.ascx
is the name of theascx
fileContoso
is the name of the element we will use to reference this user controluc
is a bit of text we will have to put in front ofuc:Contoso
(i useuc
as short for user-control)Add the control to our page:
<uc:Contoso ID="Crackers" runat="server"> <ContentTemplate> Stuff goes here </ContentTemplate> </qwerty:Contoso>
And we're done!4
Edit: Forgot to add the reason the above doesn't work. Visual Studio shows the error:
Error Creating Control - Crackers
Type 'System.Web.UI.UserControl' does not have a public property named 'ContentTemplate'
Which makes sense, since
UserControl
does not have a public property namedContentTemplate
- so i can hardly blame it.Series
This question is one in the ongoing Stackoverflow series, "Templating user controls":
- 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?
Bonus Reading
- 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
Footnotes
- 1 You can't ever use that syntax. That's just an easy to read and understand form.
- 2 Nobody knows what attributes to add, or why. Add more or less attribute to taste.
- 3 Not done. Done with the UserControl, but not our work.
- 4 Not done; it doesn't work.
- 5 in the web-site (not a web application, not in a separate assembly)
解决方案Well I believe you almost got it.
BTW. The UserControl is not rendered using Visual Studio Designer, however when you run the application the control works. This is different if you use Server Controls instead, in that case, the control is displayed correctly in the Visual Studio designer
The following code works great to build templated user controls and templated server controls however, if you would like to add binding capabilities, the process is slightly different, take a look
This is the code to create a templated
UserControl
.Simple Output
Template Container
public class MyTemplateContainer : Control, INamingContainer { }
ASPX Code behind
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 Code behind
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" />
Code to add a templated Server Control
Output
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>
Template Container
namespace MyControls { [ToolboxItem(false)] public class MyTemplateContainer : Control, INamingContainer { } }
Templated Server Control
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; } } } }
References:
这篇关于如何将模板添加到用户控件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!