Extension methods add methods to existing members without inheriting, recompiling, or otherwise modifying the original type. We use this concept to create a method that extends the Table object in TX Text Control. The method ConvertToTabs converts a table to tab positions.

Table to Tabs

Table Extension Method

The following code shows the extension method:

public static class TableExtender {
public class TabRow {
public List<CellInfo> cellInfos = new List<CellInfo>();
public class CellInfo {
public byte[] Text { get; set; }
public int Left { get; set; }
public static void ConvertToTabs(this Table table, TextControl textControl) {
textControl.BeginUndoAction("Table to tab positions");
// throw exceptions when conditions are not met
if (table.NestedTables.Count > 0)
throw (new Exception("Nested tables cannot be convertetd."));
if (table.Columns.Count > 14)
throw (new Exception("Tables with more than 14 columns cannot be converted to tab positions."));
// create a new list of tab position rows to store positions and texts
List<TabRow> tabRows = new List<TabRow>();
// loop through all rows and create a TabRow object for each row
for (int row = 1; row <= table.Rows.Count; row++) {
TabRow tabRow = new TabRow();
// loop through each column to store the text and position
for (int col = 1; col <= table.Columns.Count; col++) {
TableCell curCell = table.Cells.GetItem(row, col);
byte[] cellText;
textControl.Selection.Length -= 1;
textControl.Selection.Save(out cellText, BinaryStreamType.InternalUnicodeFormat);
tabRow.cellInfos.Add(new CellInfo() { Text = cellText, Left = curCell.Position });
// set input position after table
TableCell lastCell = table.Cells[table.Rows.Count, table.Columns.Count];
textControl.InputPosition = new InputPosition(lastCell.Start + lastCell.Length);
// loop through the created list to add the text at a new tab position
foreach (TabRow row in tabRows) {
int[] tabPositions = textControl.Selection.ParagraphFormat.TabPositions;
int colCounter = 0;
foreach (CellInfo cell in row.cellInfos) {
// tab positions cannot be 0
tabPositions[colCounter] = cell.Left != 0 ? cell.Left : 1;
// apply new tab position
textControl.Selection.ParagraphFormat.TabPositions = tabPositions;
textControl.Selection.Text = "\t"; // add tab character
// load the stored text
textControl.Selection.Load(cell.Text, BinaryStreamType.InternalUnicodeFormat);
// new row
textControl.Selection.Text = "\r\n";
// remove the table
textControl.InputPosition = new InputPosition(table.Cells[1, 1].Start);
view raw table.cs hosted with ❤ by GitHub

This method can be called on any table with fewer than 15 columns and no nested tables. The following code calls the extension method on the table at the current input position:

view raw test.cs hosted with ❤ by GitHub

How does it Work?

The method basically loops through all table rows and columns to store the position of each table cell and the text it contains in the internal TX Text Control format. In a second loop through this created list, tab positions are applied and the text is loaded separated by a tab character.