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 will split the space available equally between the rows or columns - this is useful if you want to divide your form into a couple of sections.
Percent will give your row or column a defined percentage of the controls size - it allows to have smaller and wider rows or columns, that scale when resizing the form.
Pixel will give your row or column a fixed amount of pixels - which is useful for a row of buttons or a header that you want not to scale.
You can add rows, columns, set the type, width and height of the items added to the table.
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
RowCollection. These Collections are used to keep references for all the rows (
RowControl) and columns (
ColumnControl) in my
Since there is already a collection that keeps all the controls in a list, I implemented something like a "virtual"
public class RowCollection : IList
private TableControl parentTable;
public RowCollection(TableControl parent)
this.parentTable = parent;
public bool IsReadOnly
object IList.this[int index]
throw new NotSupportedException("IList.this");
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.
public RowControl this[int index]
return parentTable.Controls[index] as RowControl;
TableControl, the types
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:
public RowCollection Rows
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
protected override void OnControlAdded(ControlEventArgs e)
if (e.Control is ColumnControl)
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:
public class RowControl : System.Windows.Forms.Panel
public class TableControl : System.Windows.Forms.Panel