如何将模板添加到用户控件? [英] How to add a Templating to a UserControl?

查看:222
本文介绍了如何将模板添加到用户控件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题已经被问过

但它不会伤害再次问它:


  

我如何在ASP.net模板添加到用户控件


什么至今还没有制定


  1. 开始一个新的用户控件 5 ,我称之为的Contoso

     公共部分类Contoso的:System.Web.UI.UserControl
    {
    }

    这将允许我们使用一个新的控件: 1

     <&Contoso的GT;
        东西在这里
    <&Contoso的GT;


  2. 创建一个公共的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的>


  3. 接下来,我们需要真正的使用的的的ContentTemplate 的东西,由地方添加它。我们将它添加到我们的用户控件的内部 DIV 元素之一做到这一点。

    这原本是空的我们的的.aspx 文件启动:

     <%@控制语言=C#AutoEventWireup =真codeFILE =Contoso.aspx.cs继承=Contoso的%>

    我们添加一个父 DIV ,将持有我们的的ContentTemplate 的东西:

     <%@控制语言=C#AutoEventWireup =真codeFILE =Contoso.aspx.cs继承=Contoso的%>
    < D​​IV 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 {搞定;组; }
    }


  4. 修改:表明你的类所实现的 作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 接口没有任何成员,只用来标记你的用户控件类的东西。


  5. 和我们完成了 3 。现在,我们可以用我们的aspx页面此控件。但首先,我们需要的注册它在我们的aspx页面的顶部:

     <%@注册SRC =Contoso.ascx变量名=Contoso的标签preFIX =UC%GT;

    其中:


    • Contoso.ascx ASCX的名称文件

    • 的Contoso 是元素的名称,我们将用引用这个用户的控制

    • UC 有点文字,我们将不得不把在前UC:Contoso的(我用 UC 短的的用户控件的)


  6. 控件添加到我们的页面:

     < UC:Contoso的ID =饼干=服务器>
        <&的ContentTemplate GT;
            东西放在这里
        < /&的ContentTemplate GT;
    < / QWERTY:Contoso的>


和我们就大功告成了! 4

修改:忘了补充上述不工作的原因。 Visual Studio中显示了错误:


  

错误创建控制 - 饼干


  
  

键入System.Web.UI.UserControl'没有名为'的ContentTemplate的公共属性。


这是有道理的,因为用户控件没有命名的公共属性的ContentTemplate - 所以我也很难责怪

系列

这个问题是一个在正在进行的系列#1,模板的用户控件

奖金阅读

脚注


  • 1 你永远不能使用该语法。这只是一个简单的阅读和理解的形式。

  • 2 没有人知道什么属性添加,或者为什么。添加更多或更少属性的味道。

  • 3 没有这样做。完成与用户控件,但不是我们的工作。

  • 4 未完成;这是行不通的。

  • 5 的网站(而不是一个Web应用程序,而不是在一个单独的程序)


解决方案

好吧,我相信你几乎得到了它。

BTW。该用户控件使用Visual Studio设计不渲染,但是当你运行应用程序的控制工程。如果你使用服务器控件来代替,在这种情况下,正确地在Visual Studio设计显示的控制,这是不同的。

以下code的伟大工程打造的模板化用户控件和模板化服务器控件然而,如果你想添加的绑定功能,这个过程略有不同,的看一看

下载源码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

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

  1. Start with a new UserControl5, which i'll call Contoso:

    public partial class Contoso: System.Web.UI.UserControl
    {
    }
    

    This will allow us to use a new control:1

    <Contoso>
        Stuff in here
    <Contoso>
    

  2. Create a public ContentTemplate property of type ITemplate:

    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>
    

  3. 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 internal div 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 our ContentTemplate 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 parent div 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; }
    }
    

  4. 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 your UserControl class as something.

  5. 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 the ascx file
    • Contoso is the name of the element we will use to reference this user control
    • uc is a bit of text we will have to put in front of uc:Contoso (i use uc as short for user-control)
  6. 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 named ContentTemplate - so i can hardly blame it.

Series

This question is one in the ongoing Stackoverflow series, "Templating user controls":

Bonus Reading

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

Download Source Code

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆