【问题标题】:ASP.NET Templated ControlASP.NET 模板化控件
【发布时间】:2009-08-17 13:16:56
【问题描述】:

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

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

我已经编辑了我的示例,希望能阐明我在寻找什么。感谢大家提供 MSDN 链接。我已经经历过这些了。 我正在尝试构建的是一个数据输入控件,它将为我自动格式化表格。我们做了很多数据输入网络表单,我想缩短实施时间。

<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 
{ 
   . 
   . 
   . 
}

【问题讨论】:

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


    【解决方案1】:

    你的实现有些奇怪。很难理解您想要做什么,要么构建模板化控件,要么构建一个可以添加子控件列表的控件。

    对于模板化方法,您必须执行以下操作:

    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>
    

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

    【讨论】:

    • 关闭,但我需要进一步扩展。请参阅我编辑的问题。
    • 嗯..好吧。只需添加另一个属性,例如 ITemplate 类型的“内容”,然后继续。它应该工作。不需要你收藏的东西。在模板中你可以放任何你想要的东西,这样你就可以忘记 FieldCollection。否则,您想要实现的不是模板,您必须采用 FieldCollection 方式。这是两个不同的东西。
    【解决方案2】:

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

    我还注意到您的模板不是从 ITemplate 接口派生的。像往常一样,ASP.Net 也使用 System.Web.UI.Control 作为这个实现的基类。

    【讨论】:

      【解决方案3】:

      我使用了以下代码:

      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>
      

      这将是帧的底部

      【讨论】:

        猜你喜欢
        • 2011-05-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多