locked
Custom Control Property Collections RRS feed

  • Question

  • Hey All

    I am trying to write a custom control that has one of its properties as a collection of panel controls. These panel controls are to go inside a main panel inside the custom control. How can I get the designer to add the collection of panel controls to the main panel control?

    Thanks in advance.

    Tuesday, April 26, 2011 2:38 PM

Answers

  • Hey, it's much easier in WinForm Controls. Hope this detailed explanation will make it clear. Simple difference is instead of "Render" you need to use "OnPaint"

    The Control Class

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    
    namespace TestWinFormApp
    {
      public class TestControl : Control
      {
        public IList<Panel> Items = new List<Panel>();
            
    
        //Component
        private System.ComponentModel.Container com = null;
        
        //Constructor
        public TestControl()
        {
          
        }
    
        //This is instead of Render method
        protected override void OnPaint(PaintEventArgs e)
        {
          base.OnPaint(e);
          //Add your custom rendering or painting here
          //Ex:
          foreach (Panel pnl in this.Items)
          {
            this.Controls.Add(pnl);
          }
        }
    
        //Dispose
        protected override void Dispose(bool disposing)
        {
          if (disposing)
          {
            if (com != null)
              com.Dispose();
          }
          base.Dispose(disposing);
        }
    
    
      }
    }
    

    The Initializer where you are using...

    //Test Control
        private TestControl tc;
    
    
    private void InitializeComponent()
        {
          
          this.SuspendLayout();
          tc = new TestControl();
          
          // 
          // Form1
          // 
          this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
          this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
          this.ClientSize = new System.Drawing.Size(428, 262);
          this.Name = "Form1";
          this.Text = "Form1";
          this.Load += new System.EventHandler(this.Form1_Load);
          this.ResumeLayout(false);
    
          //Server Control. Here I have added the style of the control
          this.tc.BackColor = System.Drawing.Color.Brown;
          tc.Width = 300;
          tc.Height = 200;
          this.Controls.Add(tc);
        }
    

     

    Adding childing controls to it...

    public Form1()
        {
          InitializeComponent();
          tc.Items.Add(new Panel() { BackColor = Color.Black, Width = 100, Height = 100 });
        }

     

     

     

     


    Anirban Bhattacharya (Lead Consultant - ESSPL)
    • Marked as answer by tompsonn Thursday, April 28, 2011 1:41 PM
    Thursday, April 28, 2011 1:38 PM

All replies

  • Add a variable in the Custom Control as
    public IList<Panel> Items = new List<Panel>();

    Render those using the virtual method as
    protected override void Render(HtmlTextWriter writer)

    In the designer use it as
    MyControl.Items.Add(new Panel(){ID="Panel1".....});

    Thanks
    Anirban Bhattacharya (Lead Consultant - ESSPL)
    Wednesday, April 27, 2011 10:53 AM
  • Thanks for your reply

    I'm not quite sure what you mean by " Render those using the virtual method as" and "In the designer use it as"...

    Basically I want to get the added panels to show up at design time....

    Could you elaborate further? Thanks!


    (This is a C# WinForms application, FYI)

    Wednesday, April 27, 2011 11:36 AM
  • Hi,

    If you are creating a Custom Control inheriting WebControl there is always a virtual method available to make sure that it's Childs are rendered properly.

    Here is a simplete custom control. Where you can set the main Panel and add child panels as TestControl1.Items.Add(new Panel(){ID="this..."});

    Hope this explains.

    using System;
    using System.Data;
    using System.Configuration;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    using System.Collections.Generic;
    
    namespace MiscControls
    {
      [ToolboxData(@"<{0}:TestControl runat=""server"" \>")]
      public class TestControl : WebControl
      {
        public IList<Panel> Items = new List<Panel>();
    
        //Main Panel
        Panel MainPanel{get; set;}
        //Auto PostBack
        public bool AutoPostBack { get; set; }
    
        //Child Controls
        protected override void CreateChildControls()
        {
          base.CreateChildControls();
          if (MainPanel != null)
          {
            foreach(Panel pnl in Items)
              MainPanel.Controls.Add(pnl);
          }
        }
    
        //Render
        protected override void Render(HtmlTextWriter writer)
        {
          base.Render(writer);
          //You can write your own render process here.
        }
      }
    
    }

     

     


    Anirban Bhattacharya (Lead Consultant - ESSPL)
    Thursday, April 28, 2011 11:34 AM
  • Anirban,

    This is a WinForms C# application. Is there an equivalent for the code you posted?

     

    Thanks so far :)

    Thursday, April 28, 2011 11:35 AM
  • Hey, it's much easier in WinForm Controls. Hope this detailed explanation will make it clear. Simple difference is instead of "Render" you need to use "OnPaint"

    The Control Class

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    
    namespace TestWinFormApp
    {
      public class TestControl : Control
      {
        public IList<Panel> Items = new List<Panel>();
            
    
        //Component
        private System.ComponentModel.Container com = null;
        
        //Constructor
        public TestControl()
        {
          
        }
    
        //This is instead of Render method
        protected override void OnPaint(PaintEventArgs e)
        {
          base.OnPaint(e);
          //Add your custom rendering or painting here
          //Ex:
          foreach (Panel pnl in this.Items)
          {
            this.Controls.Add(pnl);
          }
        }
    
        //Dispose
        protected override void Dispose(bool disposing)
        {
          if (disposing)
          {
            if (com != null)
              com.Dispose();
          }
          base.Dispose(disposing);
        }
    
    
      }
    }
    

    The Initializer where you are using...

    //Test Control
        private TestControl tc;
    
    
    private void InitializeComponent()
        {
          
          this.SuspendLayout();
          tc = new TestControl();
          
          // 
          // Form1
          // 
          this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
          this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
          this.ClientSize = new System.Drawing.Size(428, 262);
          this.Name = "Form1";
          this.Text = "Form1";
          this.Load += new System.EventHandler(this.Form1_Load);
          this.ResumeLayout(false);
    
          //Server Control. Here I have added the style of the control
          this.tc.BackColor = System.Drawing.Color.Brown;
          tc.Width = 300;
          tc.Height = 200;
          this.Controls.Add(tc);
        }
    

     

    Adding childing controls to it...

    public Form1()
        {
          InitializeComponent();
          tc.Items.Add(new Panel() { BackColor = Color.Black, Width = 100, Height = 100 });
        }

     

     

     

     


    Anirban Bhattacharya (Lead Consultant - ESSPL)
    • Marked as answer by tompsonn Thursday, April 28, 2011 1:41 PM
    Thursday, April 28, 2011 1:38 PM
  • Perfect. Bit more tinkering from myself and that'll do it.

    Thanks a bunch!

    Thursday, April 28, 2011 1:42 PM