vbCity Leader (and Microsoft MVP) Ged Mead showed how to create a FlowDocument in his article published on devCity.com.
I got the challenge recently to display a data inserted in a table in a flowdocument. So I embarked on my quest.
I knew that what I wanted could be done because some quick testing with XAML I was easily able to add a table to my flowdocument.

Which gives an output like the following.

My challenge, however, was that I needed to be able to do this with Visual Basic.NET code behind as the data that was to be displayed in the table was going to be read from a file.
I made my first mistake almost immediately. (Now that is probably not the best thing for me to admit when I am trying to convince everyone that I actually know what I am talking about, but hey, I am big enough to admit my mistakes.)
The mistake I made was trying to use the wrong table. I was able to create and insert the data from the file into the table I created with VB code, but when I tried to add the table to the flowdocument I couldn’t. No matter what I tried, I was just unable to add the table and after a couple of days, I finally gave up and asked for help. Microsoft MVP Jay Harlow quickly pointed me in the right direction.
What the problem was is that there are more than one table that is accessible for use in the .NET Framework. I was trying to use the table in the System.Web Namespace, but in fact I needed to be using the table from the System.Windows.Documents Namespace.
Once I was referencing the correct table, the whole project came together quite nicely.
(While the project I was doing required reading data from a file that will be outside the scope of this blog post. In this post I will just be showing how to hardcode data into a table in a flowdocument.)
The first thing that is needed is to Import the Namespace to give us access to use a table.

Next declare two form level variables. One variable is declared as a flowdocument and the other is declared as a table.

In the event you want to create the table in, I used the Initialized event of the form for this example, set the two variables to a new instance of a flowdocument and table respectively.

Now that there is a flowdocument and a table the table needs colums, rows and content for the table.
The columns are the first things to be added to the table. Columns are added to the collection, or array, of columns of the table. For this example I am going to add four columns to the table.

With the columns added, Rows can now be added to the table. Like columns, rows are also held in an array of rows. Where rows differ from columns is rows are actually part of RowGroups. You can have several rows in a rowgroup and more than one rowgroup in a table.
So to start a new rowgroup must be added to the rowgroups of the table.

and into that rowgroup a new row is added.

Although you still can’t see it if you were to look at the form itself, the table now has four columns and one row. Into the row Cells need to be added.
At this point there is a great deal of possibilities to how what the table is going to look like. While you can set some formatting for the table with changing the properties of the table and rows, you have much greater control over the look of the table by manipulating the properties of the cells.
For this table I want to have a header that stretches across the entire top of the table, so while I can have four cells in the row (I can do this because I added four columns to the table earlier) only one is going to be added to the row. The cell will then be made to stretch over the entire width of the table.

There is quite a bit going on in the above line of code. A new TableCell is added to the collection of cells of the row and to add content to the cell a new Paragraph is used as a parameter of the tablecell and a new Run of text is passed as a parameter of the paragraph.
After adding what is going to be the title of the table, some formatting can be assigned.

The first line of code above tells the cell to span the entire width of the four columns of the table. (If you have worked with tables in Microsoft Word think of this process to be like merging cells in a table.)
The second line sets the size of the font to make the text stand out as a title and the third line centers the text in the cell. (By default the text alignment of a table, row or cell is left.)
The fourth line of code makes the font bold.
The fifth line of code sets the colour of the text in the cell and the sixth line gives the cell a colour for the background.
If we add two more lines of code the table can be shown in the FlowDocumentReader.
The table is first added to the Blocks of the flowdocument that was declared at the beginning of our code then the flowdocument is assigned as the document of the FlowDocumentReader of the form.

(Note: Interestingly enough it does not seem to matter where you place the code to add the table into the flowdocument and make the document of the reader to be your flowdocument. The code can be added just after the declaration of the flowdocument and table or anywhere in the middle of the code that formats and populates the table. Personally I put these two lines at the very end prior to displaying the flowdocument.)
Now when the project is run, you can see the table starting to take shape.

Putting Headers for each column are next to be added to the table.
A new row is added to the rowgroup of the table then four cells are added to the row with content also being added to each cell.

You can see by the Index number of the rows that the new cells have been added to the second row. Like all .NET arrays the rows array of a rowgroup, as is the rowgroup itself, are zero based so if you need to remember that the actual row number is one higher than the index number.
Running the project shows that the columns now have headers.

The table is really starting to look like a table now.
A line under the column headers keeps the data in the columns separated from the headers. To accomplish this, a new row is added under the row of headers. One cell is added to the row and it will span the four columns like the title cell does. To make the line, the border property of the cell is going to be used. The top border of the cell will be made larger and given a colour.
To make the border thicker a New Thickness is applied to the cell. Thickness can either be set by passing a single parameter to the new thickness, which would give the same thickness to all sides of the cell, or you can pass four parameters and assign separate thicknesses to each side. While it does not make any difference to what I am demonstrating here, I have only assigned a thickness to the top border of the cell. I could have just as easily assigned a uniform thickness to the cell.

Now the contents of the table will be separated from the column headers by a red line.

With the formatting of the table set out, it is time to add some content into the table itself.
For this example I am going to use a For…Next Loop to populate the table.

Two Integer variables are declared. The first is used to keep track of the index of the row in the rowgroup. The variable is declared with a value of 3 because the first line that will be added in the loop will be the fourth element of the array of rows. The second variable is just used for adding content to each of the cells as they are added to the row.
In the loop the first line of code adds a new row to the table then the next four lines add the cells to the row and put some content in the cell. In this example the content of the cells in the row will just have the text "Number: 0" to "Number: 97".
In the last line the value of the variable j is incremented by 1 so the content number of the next row will be one higher than the last.
Now when the project is run the table is complete. The table starts with:

and six pages later going to:
