views:

595

answers:

5

Hello, I'm attempting to build a templated control. You'll see that as part of the Field section, I'd like to be able to define controls as children. When I attempt to compile I'm receiving the error message "MyTemplateControl.Field' does not have a public property named 'Button'". Does anyone know how to accomplish what I'm trying to do?

Below you'll find an example XHTML markup, and below that my control implementation.

I've editted my example to hopefully clarify what I'm looking for. Thanks everyone for the MSDN links. I've been through those already.
What I'm trying to build is a data entry control that will auto format a table for me. We do a lot of data entry webforms, and I'd like to ease the implementation time.

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

I think you should have to read an article - http://msdn.microsoft.com/en-us/library/aa478964.aspx

SUMMARY:Building a Non-Databound Templated Server Control - To demonstrate the use of templates in non-databound controls, let's build a custom server control that will provide a template for customization of output.

adatapost
A: 

GridView also doesn't allow such manipulation, Instead use MyForm1.FindControl("mybutton")

Also I have notice your template is not derived from ITemplate interface. As usual ASP.Net also uses System.Web.UI.Control as base class for this impl.

Dewfy
+2  A: 

There's something strange in your implementation. It's difficult to understand what you'd like to do, either to build a templated control, or a control on which you can add a list of child controls.

For the templated approach you'd have to do something like this:

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

The usage would then look like

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

You still have to add the appropriate annotations to configure the behavior of the designer. I just wrote this down quickly to give you an idea.

Juri
Close, but I need it to be further extended. See my editted question.
ehm..well. Just add another property like "Content" which is of type ITemplate and continue. It should work. Your thing with the collection isn't needed. Within a template you can put whatever you want, so you can forget about the FieldCollection. Otherwise what you want to achieve is not a template and you have to go for the FieldCollection-way. These are two different things.
Juri
A: 

Here is a good example on how to build a templated control (with headers/footers etc)

http://dotnetslackers.com/VB%5FNET/re-17169%5FRendering%5Fa%5Fdatabound%5FUL%5Fmenu.aspx

(example code in both VB.NET abd C#)

Mark Redman
A: 

I used the following code:

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

and ascx page look like:

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

this will be top of frame

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

this will be bottom of frame

Yuriy Zaletskyy