asp.net - 如何将模板添加到用户控件?

标签 asp.net user-controls templating webusercontrol

这个问题之前有人问过

  • 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?



    到目前为止没有什么效果
  • 从一个新的 UserControl 开始5,我会调用Contoso :
    public partial class Contoso: System.Web.UI.UserControl
    {
    }
    

    这将允许我们使用新控件:1
    <Contoso>
        Stuff in here
    <Contoso>
    
  • 创建公众 ContentTemplate ITemplate 类型的属性:
    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" %>
    

    我们添加一个父 div这将容纳我们的ContentTemplate东西:
    <%@ Control Language="C#" AutoEventWireup="true" CodeFile="Contoso.aspx.cs" Inherits="Contoso" %>
    <div id="ContentDiv" runat="server"></div>
    

    然后我们填充ContentTemplate塞进那个 parent 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 接口(interface)没有任何成员,仅用于标记您的UserControl类的东西。
  • 我们完成了3。我们现在可以在我们的 aspx 页面中使用这个控件。但首先我们需要 “注册”它在我们的 aspx 页面的顶部:
    <%@ Register src="Contoso.ascx" TagName="Contoso" tagprefix="uc" %>
    

    在哪里:
  • Contoso.ascxascx 的名称文件
  • Contoso是我们将用来引用此用户控件的元素的名称
  • uc是我们必须放在 uc:Contoso 前面的一段文字(我使用 uc 作为用户控制的缩写)
  • 将控件添加到我们的页面:
    <uc:Contoso ID="Crackers" runat="server">
        <ContentTemplate>
            Stuff goes here
        </ContentTemplate>
    </qwerty:Contoso>
    

  • 我们完成了!4

    编辑 : 忘记添加上面不起作用的原因。 Visual Studio 显示错误:

    Error Creating Control - Crackers

    Type 'System.Web.UI.UserControl' does not have a public property named 'ContentTemplate'



    enter image description here

    这是有道理的,因为 UserControl没有名为 ContentTemplate 的公共(public)属性- 所以我很难责怪它。

    系列

    这个问题是正在进行的 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 应用程序,不是在单独的程序集中)
  • 最佳答案

    好吧,我相信你几乎明白了。

    顺便提一句。 UserControl 不是使用 Visual Studio 设计器呈现的,但是当您运行应用程序时,该控件可以工作。如果您改用服务器控件,情况会有所不同,在这种情况下,控件会在 Visual Studio 设计器中正确显示

    以下代码非常适合构建 模板化用户控件和模板化服务器控件但是,如果您想添加绑定(bind)功能,则过程略有不同,take a look

    Download Source Code

    这是创建模板 UserControl 的代码.

    简单输出

    enter image description here

    模板容器

    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"));
            }
        }
    }
    

    澳交所
    <%@ Control Language="C#" AutoEventWireup="true" CodeFile="WebUserControl.ascx.cs" Inherits="WebUserControl" %>
    
    <asp:PlaceHolder runat="server" ID="myPlaceHolderTag" />
    

    添加模板化服务器控件的代码

    输出

    enter image description here

    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
  • 关于asp.net - 如何将模板添加到用户控件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11658053/

    相关文章:

    node.js - 在 Jade 中调用 mixin 时, "+"和 mixin 关键字有什么区别?

    c# - EntityFramework 同表多对多关系

    c# - 在 Windows 窗体中以编程方式添加新的用户控件

    .net - 如何使 Silverlight UserControl 成为内容容器?

    c# - 需要两个用户控件(winforms)进行通信时的最佳实践

    javascript - mootools 的客户端模板库?

    c++ - 在没有模板的情况下评估另一个类的动态函数指针

    asp.net - EntityFramework连接问题

    asp.net - 使用 HttpContextScoped() 时 StructureMap 不会处理数据上下文

    javascript - 将参数从 View 传递到 Controller Razor