Click here to Skip to main content
Email Password   helpLost your password?

Introduction

Have you ever worked on ASP.NET and than moved back to Windows programming using Windows forms? Did you miss something?

Well I did! Why are there no controls like the HTML <table>, <tr> and <td> tags (and controls) to polish your layout?

Microsoft will introduce them with the next version of Windows forms. If you do not want to wait, you might try this control.

Using the code

I have created three controls that will help you layout your Windows Forms applications using a HTML <table> like control without writing one line of code.

All you have to do is compile the TableControl project, add the TableControl.dll to your solution and add the TableControl Component to your Visual Studio Toolbox using Add/Remove Items... in the context menu.

After that you can use the TableControl just like any other Windows Forms control and drag it onto your form.

Add a couple of rows to the table and columns to the rows using the Collection Editor and you are all set. Drag any Windows Forms control to the columns and they will move just like HTML items added to a table.

To make your table useful, you have to specify how you want your rows and columns scaled. You have three choices: auto, percent, or pixel.

You can add rows, columns, set the type, width and height of the items added to the table.

The TableControl does not allow to add anything but a row to the table using the designer. And a row does not allow anything to be added but a column.

Points of Interest

I found it very easy to build a control and implement Visual Studio Designer support for custom collections.

All you have to do is implement the IList interface as I did for ColumnCollection and RowCollection. These Collections are used to keep references for all the rows (RowControl) and columns (ColumnControl) in my TableControl.

Since there is already a collection that keeps all the controls in a list, I implemented something like a "virtual" IList collection.

//

// A RowCollection is a proxy to the Controls collection inside

//

public class RowCollection : IList
{
    private TableControl parentTable;

    public RowCollection(TableControl parent)
    {
        this.parentTable = parent;
    }
    public bool IsReadOnly
    {
        get
        {
            return parentTable.Controls.IsReadOnly;
        }
    }

    object IList.this[int index]
    {
        get 
        {
            return this.parentTable.Controls[index];
        }
        set 
        {        
            throw new NotSupportedException("IList.this");
        }
    }
...

The RowCollection IList implementation always uses its parent's Controls collection to retrieve a row.

To use this collection with the Visual Studio Designer, you have to implement a public Indexer which allows you to access typed objects that are in the collection.

//

// This is the Indexer the designer is looking for...it will

// offer a collection editor for items of type RowControl

//

public RowControl this[int index]
{
    get
    {
        return parentTable.Controls[index] as RowControl;
    }
}

In my TableControl, the types TableControl, RowControl and ColumnControl are all derived from System.Windows.Forms.Panel. This adds support for borders and background colors - getting closer to an HTML table.

To make the TableControl easier to use in Visual Studio, I added public properties to the rows collection not only to the TableControl but also to the RowControl and the ColumnControl. This is really no trick since the collections are "virtual" anyway:

//

// This is the Indexer the designer is looking for...it

// will offer a collection editor for items of type RowControl

//

public RowCollection Rows
{
    get 
    {
        if (this.Parent is TableControl)
            return (this.Parent as TableControl).Rows;
        throw new ArgumentException("Row Control is not placed in a table.");
    }
}

This is really all you have to do to bring up the collection editor for the rows and columns from a table, row or column and have your own types inserted into your application's code:

To stop the designer from allowing other controls to be dragged directly into my table or my row, I added an override to my RowControl and TableControl implementation:

//

// Only allow a ColumnControl to be added 

//

protected override void OnControlAdded(ControlEventArgs e)
{
    if (e.Control is ColumnControl)
        base.OnControlAdded (e);
    else
        throw new ArgumentException("You cannot add a " + 
          "Control directly to a row. Please insert a Column.");
}

Finally, I do not want to allow anybody to drag a row or column to a form:

//

// Do not add RowControl and ColumnControl to the Toolbox,

// only TableControl can be added

//

ToolboxItem(false)]
public class RowControl : System.Windows.Forms.Panel
{
...

[ToolboxItem(true)]
public class TableControl : System.Windows.Forms.Panel
{
...

That's all.

History

First release.

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
QuestionCan't add the control to the toolbox uner VS2008
srjacob
16:42 30 Mar '09  
I must be dense, but I can't seem to add the control to the toolbox. Can anyone please offer me some advice here.

Thanks
Generaladd text in column of table
EEmaan
1:19 30 May '07  
Hi!
i have used ur dll in my project now i can add different controls in table by using RowControl and ColumnControl.
i add rowcontrol in table and and then column control in rowcontrol.after that i can differnt controls in column control but i m unable to add text myself in column control as i can in table control of web application like i can write like (tablecell.text="abc") but here i couldnot find property like (columncontrol.text="abc").
thanx
GeneralAnchor Bug
Gianni Gardini 2
8:18 5 Sep '06  
Using the TableControl with row.HeightType == RowControl.HeightMeasurement.Pixel (and maybe even with the other option) you can have wrong row height resize in some situations, for example, adding and removing a statusbar.

I fixed this replacing:
public RowControl()
{
// This call is required by the Windows.Forms Form Designer.
InitializeComponent();

this.Layout +=new LayoutEventHandler(RowControl_Layout);

this.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom;
this.Dock = DockStyle.None;

}

With:
public RowControl()
{
// This call is required by the Windows.Forms Form Designer.
InitializeComponent();

this.Layout +=new LayoutEventHandler(RowControl_Layout);

this.Anchor = AnchorStyles.Top | AnchorStyles.Right; this.Dock = DockStyle.None;


}

GeneralBug
_iTcHy_
2:36 21 Jun '05  
In RowCollection.cs:

Replace
public void Clear()
{
foreach(RowControl ctrl in this.parentTable.Controls)
if (ctrl != null)
this.parentTable.Controls.Remove(ctrl);
}

with
public void Clear()
{
for (int i=this.parentTable.Controls.Count - 1; i>=0; i--)
{
RowControl ctrl = this.parentTable.Controls[i] as RowControl;
if (ctrl != null)
this.parentTable.Controls.RemoveAt(i);
}
}


In ColumnCollection.cs:

Replace

public void Clear()
{
foreach(ColumnControl ctrl in this.parentRow.Controls)
if (ctrl != null)
this.parentRow.Controls.Remove(ctrl);
}

with
public void Clear()
{
for (int i=this.parentRow.Controls.Count - 1; i>=0; i--)
{
ColumnControl ctrl = this.parentRow.Controls[i] as ColumnControl;
if (ctrl != null)
this.parentRow.Controls.RemoveAt(i);
}
}


I'll leave it up to you to figure out why, shouldn't be to difficult Wink

Greetz _iTcHy_
GeneralCouldn't build
LiamD
5:24 9 Jun '05  
I unzipped the software TableControl.zip to C:\tmp

I opened the Sample\TableCtrl.sln file. On trying to build I got this error:-

C:\tmp\TableControl\Sample\Form1.cs(17): The type or namespace name 'LayoutControl' could not be found (are you missing a using directive or an assembly reference?)

How should I get round this?
GeneralRe: Couldn't build
Bryan Baker
13:15 20 Jun '05  
One of the "using" statements in the TableControl code files was missing the ending "g". Once I fixed that, the projects compiled successfully.

Very useful sample, by the way!
Generalyeah, that's good
_iTcHy_
2:44 19 May '05  
Finally, this is what I was looking for.


I preferred removing these two lines in the constructor:
this.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Bottom;
this.Dock = DockStyle.None;

Otherwise Anchor and Dock settings I made in the property window were ignored/overridden.


Great work, thx!
GeneralDoes it support something like "border-color", "border-width", etc.?
percyboy
20:32 7 Apr '05  
Really a nice idea!

Does it support something like "border-color", "border-width", etc.?

In the picture you posted, I havn't seen such settings. Will it support border-drawing in the future?

Thanks!

GeneralDesigner Serialization
andrebrogli
12:37 1 Mar '04  
You need to add serialization attributes for the designer, otherwise your nicely designed table will go up in smoke.

in TableControl.cs:

[
Category("Table Control"),
Description("Rows in this table"),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
EditorAttribute(typeof(System.ComponentModel.Design.CollectionEditor), typeof(System.Drawing.Design.UITypeEditor))
]
public RowCollection Rows
{
get
{
if (this.rows == null)
this.rows = new RowCollection(this);
return this.rows;
}
}

in RowControl.cs

[
Category("Table Control"),
Description("Columns"),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
EditorAttribute(typeof(System.ComponentModel.Design.CollectionEditor), typeof(System.Drawing.Design.UITypeEditor))
]
public ColumnCollection Columns
{
get
{
if (this.columns == null)
this.columns = new ColumnCollection(this);
return this.columns;
}
}
--Andre
GeneralGreat stuff...
pikipoki
11:37 1 Mar '04  
I've been missing something like this since I switched from Delphi.

Thanks.
Dejan
GeneralAny URL of the information...
Uwe Keim
18:16 29 Feb '04  
You wrote: "[...]Microsoft will introduce them with the next version of Windows forms.[...]"
Can you give any source of your information? I heard nothing about WinForms next version, would be quite interesting, I guess.

--
- Free Windows-based CMS: www.zeta-software.de/enu/producer/freeware/download.html - See me: www.magerquark.de - MSN Messenger: uwe_keim@hotmail.com

GeneralRe: Any URL of the information...
pikipoki
11:39 1 Mar '04  
In "Whidbey" aka VS.NET 2004 technology preview beta (MSDN subscribers can request it on DVD from Microsoft) you can see and test such a control.

LP,
Dejan

GeneralRe: Any URL of the information...
john_coleman
8:21 5 Apr '04  
It's part of Avalon the new presentation API for longhorn. The markup language is called XAML.

See this article.


Last Updated 29 Feb 2004 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010