ASP.NET模板化控件

时间:2009-08-17 13:16:57

标签: asp.net custom-server-controls itemplate

我正在尝试构建模板化控件。您将看到作为Field部分的一部分,我希望能够将控件定义为子项。当我尝试编译时,我收到错误消息“ MyTemplateControl.Field'没有名为'Button'的公共属性 ”。有谁知道如何完成我想要做的事情?

下面你会找到一个示例XHTML标记,下面是我的控件实现。

  

我编辑了我的例子,希望澄清我在寻找什么。谢谢大家的MSDN链接。我已经经历过那些了   我正在尝试构建的是一个数据输入控件,它将为我自动格式化一个表。我们做了很多数据输入webforms,我想缩短实现时间。

<cc1:MyForm ID="MyForm1" runat="server">
    <ViewTemplate>
        <cc1:Field Question="What is your name?">
            <asp:Label ID="myLabel" runat="server" />
        </cc1:Field>
    </ViewTemplate>
    <EditTemplate>
        <cc1:Field Question="What is your name?">
            <asp:Textbox ID="myTextbox" runat="server" />
        </cc1:Field>
    </EditTemplate>
</cc1:MyForm>

public class MyForm : WebControl, INamingContainer
{
    private FieldCollection _fieldCollection;
    private FieldCollection _field2Collection;

    public FieldCollection ViewTemplate
    {
        get
        {
            if (_fieldCollection == null)
            {
                _fieldCollection = new FieldCollection();
            }
            return _fieldCollection;
        }
    }

    public FieldCollection EditTemplate
    {
        get
        {
            if (_field2Collection == null)
            {
                _field2Collection = new FieldCollection();
            }
            return _field2Collection;
        }
    }
}

public class FieldCollection : CollectionBase
{
   .
   .
   .
}

[ParseChildren(false)]
public class Field 
{ 
   . 
   . 
   . 
}

3 个答案:

答案 0 :(得分:2)

您的实施中有一些奇怪的东西。很难理解你想要做什么,要么建立模板化控件,要么控制你可以添加子控件列表。

对于模板化的方法,你必须做这样的事情:

public class MyForm : WebControl, INamingContainer
{

   private TemplateOwner templateOwner{ get; set; }

   private ITemplate _Content;
   public ITemplate Content
   {
      get
      {
         return this._Content;
      }
      set
      {
         _Content = value;
      }
   }

   protected override void CreateChildControls()
   {
      base.Controls.Clear();

      templateOwner = new TemplateOwner();
      this.Content.InstantiateIn(templateOwner);

      this.Controls.Add(templateOwner);
   }

   ...
}

[ToolboxItem(false)]
public class TemplateOwner : WebControl{

  public TemplateOwner():base(HtmlTextWriterTag.Div)
  {
  }
}

用法看起来像

<cc1:MyForm ID="MyForm1" runat="server">
    <Content>
        <!-- Place whatever HTML, ASP.net controls etc you like -->
    </Content>
</cc1:MyForm>

您仍然需要添加相应的注释来配置设计器的行为。我只是快速写下来给你一个想法。

答案 1 :(得分:0)

GridView也不允许这样的操作, 而是使用MyForm1.FindControl(“mybutton”)

此外,我注意到您的模板不是从ITemplate界面派生的。像往常一样,ASP.Net也使用System.Web.UI.Control作为此impl的基类。

答案 2 :(得分:0)

我使用了以下代码:

public partial class SmallFramedControl : UserControl, INamingContainer 
{
    private TemplateOwner templateOwner { get; set; }
    private ITemplate _Content;
    public ITemplate Content
    {
        get
        {
            return this._Content;
        }
        set
        {
            _Content = value;
        }
    }

    protected override void CreateChildControls()
    {
        //base.Controls.Clear();
        templateOwner = new TemplateOwner();
        this.Content.InstantiateIn(templateOwner);
        plchAdd.Controls.Add(templateOwner);
    }



    protected void Page_Load(object sender, EventArgs e)
    {

    }
}

[ToolboxItem(false)]
public class TemplateOwner : WebControl
{
    public TemplateOwner()
        : base(HtmlTextWriterTag.Div)
    {
    }
}

和ascx页面看起来像:

<%@ Control Language="C#" AutoEventWireup="true"
            CodeBehind="SmallFramedControl.ascx.cs"
            Inherits="OtPortalNewDesign.UserControls.SmallFramedControl" %>

这将是框架的顶部

<asp:PlaceHolder ID="plchAdd" runat="server"></asp:PlaceHolder>

这将是框架的底部