19

I'm rendering a Table in a WPF FlowDocument using code-behind. But, I've been unable to find an example that shows how to make the table use only the space needed based on content. Instead the table takes up all available width, which I don't want, nor do I want to have to specify a exact pixel sizes.

I'm clearly missing something simple, anyone see it?

var fd = new FlowDocument();

Table t = new Table();

t.BorderBrush = Brushes.Black;
t.BorderThickness = new Thickness(2);

// I thought this would do what I wanted...
t.Columns.Add(new TableColumn() { Width = GridLength.Auto });
t.Columns.Add(new TableCOlumn() { Width = GridLength.Auto });

TableRowGroup trg = new TableRowGroup();

TableRow currentRow = new TableRow();
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("ABC"))));
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("XYZ"))));
trg.Rows.Add(currentRow);

currentRow = new TableRow();
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("123"))));
currentRow.Cells.Add(new TableCell(new Paragraph(new Run("789"))));
trg.Rows.Add(currentRow);

t.RowGroups.Add(trg);

fd.Blocks.Add(t);
skaffman
  • 398,947
  • 96
  • 818
  • 769
Walt Stoneburner
  • 2,562
  • 4
  • 24
  • 37
  • The closest StackOverflow question I found related to this was this one, http://stackoverflow.com/questions/1491285/wpf-flowdocument-table-autofit-option, but I'm interested in the code behind, not XAML, and I'm not so sure this guy got his question answered either. – Walt Stoneburner Sep 29 '10 at 14:35
  • 1
    This appears to be a known issue: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/a073e483-fc48-426d-9f88-e1260c9c9142 – DK. Oct 04 '10 at 21:11
  • I had bumped into that but figured that Microsoft had gotten it's act together since 2008. But, yeah, that appears to be a manifestation of the problem I'm facing. – Walt Stoneburner Oct 05 '10 at 13:38
  • It was suggested that I try `Width = new GridLength(1, GridUnitType.Star)` in the code above, however some experimentation showed this grabbed up all available space as well. It was good idea that was worth a shot, but it didn't get as close as the grid solution. – Walt Stoneburner Oct 07 '10 at 21:54
  • After setting FlowDocument.ColumnWidth = 999999 and TableColumn.Width = new GridLength(1, GridUnitType.Star) everythings is just fine. must underline - .Net version 4. – ProfyTroll Jan 22 '12 at 21:25

3 Answers3

10

I do not think this is possible... the only hacky workaround is to use the BlockUIContainer and a real grid!

var fd = new FlowDocument();

Grid g = new Grid();

g.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Auto });
g.ColumnDefinitions.Add(new ColumnDefinition() { Width = GridLength.Auto });

g.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });
g.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });

var t1 = new TextBlock() { Text = "ABC", Margin = new Thickness(5,3,5,3) };
t1.SetValue(Grid.ColumnProperty, 0);
t1.SetValue(Grid.RowProperty, 0);
g.Children.Add(t1);

var t2 = new TextBlock() { Text = "XYZ", Margin = new Thickness(5, 3, 5, 3) };
t2.SetValue(Grid.ColumnProperty, 1);
t2.SetValue(Grid.RowProperty, 0);
g.Children.Add(t2);

var t3 = new TextBlock() { Text = "123", Margin = new Thickness(5, 3, 5, 3) };
t3.SetValue(Grid.ColumnProperty, 0);
t3.SetValue(Grid.RowProperty, 1);
g.Children.Add(t3);

var t4 = new TextBlock() { Text = "789", Margin = new Thickness(5, 3, 5, 3) };
t4.SetValue(Grid.ColumnProperty, 1);
t4.SetValue(Grid.RowProperty, 1);
g.Children.Add(t4);

fd.Blocks.Add(new BlockUIContainer(g));
rudigrobler
  • 17,045
  • 12
  • 60
  • 74
  • I'm coming to the conclusion that my original code should work, but that there's a bug in WPF (and I doubt that will get resolved in a timely manner for me to make use of it). This "hacky workaround" was able to give me a viable short term solution. Insightful use of BlockUIContainer to get the Grid into the FlowDocument. Thanks, though a small part of me has died inside in that libraries ought to work as documented. – Walt Stoneburner Oct 07 '10 at 18:54
3

try TableCell.ColoumnSpan and TableCell.RowSpan

icaptan
  • 1,495
  • 1
  • 16
  • 36
  • 1
    This is a quick and dirty way to get a column to be larger than others, define multiple columns for it and set it's columnspan to X – Chris Ray Jul 15 '14 at 15:58
0

I know the question was asked 9 years ago, but I found out an alternate way to do this without using a BlockUIContainer which quite frankly is a pain when serializing the FlowDocument or when the user is just editing the document in a RichTextBox.

Add a PreviewMouseMove and PreviewMouseDown handler to every single table cells. In PreviewMouseMove change the cursor to SizeWE whenever adjacent to the cell border. In PreviewMouseDown capture the mouse using the RichTextBox as the source.

Add a PreviewMouseMove and PreviewMouseUp handler to the RichTextBox. In PreviewMouseMove resize the table column based on the calculated horizontal delta movement. In PreviewMouseUp release the mouse.

The tricky part is to figure where the cell borders are because there's no way out of the box to just get the cell position or width. So you have to approximate where they are by doing the sum of the PagePadding, Table Padding and column widths.

Duro
  • 1