Is there a way to add a border around the table and hide the cell borders in MigraDoc?
The default width of the borders is 0 and borders are not visible. To enable borders, set a value greater than 0.
If table is your Table object, you could write table.Borders.Width = 0.5;
You can set borders for the table and for each cell. Cells inherit border properties from the table, the column, the row unless they are overwritten at a lower stage.
Also check the SetEdge method of the Table class.
Sample code discussed here:
http://www.pdfsharp.net/wiki/Invoice-sample.ashx
My test code:
private static void TabelWithBorderTest()
{
var document = new Document();
// Add a section to the document.
var section = document.AddSection();
Table table = section.AddTable();
table.Borders.Width = 0.25;
table.Rows.LeftIndent = 0;
// Before you can add a row, you must define the columns
Column column = table.AddColumn("7cm");
column.Format.Alignment = ParagraphAlignment.Left;
Row row = table.AddRow();
row.Cells[0].AddParagraph("Text in table");
// Create a renderer for the MigraDoc document.
var pdfRenderer = new PdfDocumentRenderer(false) { Document = document };
// Associate the MigraDoc document with a renderer.
// Layout and render document to PDF.
pdfRenderer.RenderDocument();
// Save the document...
const string filename = "TableTest.pdf";
pdfRenderer.PdfDocument.Save(filename);
// ...and start a viewer.
Process.Start(filename);
}
I managed to get this down by setting each row borders visibility as false;
var document = new Document();
var page = document.AddSection();
Table table = page.AddTable();
table.Borders.Visible = true;
Column col = table.AddColumn("3cm");
col = table.AddColumn("10cm");
col = table.AddColumn("3cm");
col.Format.Alignment = ParagraphAlignment.Left;
Row row = table.AddRow();
Paragraph p = row.Cells[0].AddParagraph();
p.AddFormattedText("Top header row");
row.Cells[0].MergeRight = 2;
// then set it in visible as false like this, you can do top, left and right as well
row.Cells[0].Borders.Bottom.Visible = false;
Doesn't look nice but if anyone has a better solution do post it up
Related
I have a TableLayoutPanel, ug_degrees, with 3 columns and 1 row. Each cell gets dynamically populated with another TableLayoutPanel, degreePanel, containing 1 label and 1 textbox.
I need to get my layout to look something like this:
Right now my layout looks like this:
I'm at a loss for why I have those giant gaps between the cells, and why the row will not expand to fill its contents (a label & a textbox). I have tried to set the whole TableLayoutPanel's autosize property to true, but the columns get resized, even if I set only the rows' sizetype to autosize as well.
The properties behind the table shown are default. All non-default properties are customized in C# below.
// Dynamically load undergraduate degrees
int row = 0;
for (int i = 0; i < degrees.undergraduate.Count; i++) {
// Create and populate panel for each degree
TableLayoutPanel degreePanel = new TableLayoutPanel();
degreePanel.ColumnCount = 1;
degreePanel.RowCount = 2;
degreePanel.AutoSize = true;
foreach (RowStyle style in degreePanel.RowStyles) {
style.SizeType = SizeType.AutoSize;
}
degreePanel.BorderStyle = BorderStyle.FixedSingle;
//degreePanel.Margin = new Padding(0);
Label degTitle = new Label();
degTitle.Text = degrees.undergraduate[i].title;
degTitle.Dock = DockStyle.Fill;
TextBox degDesc = new TextBox();
degDesc.ReadOnly = true;
degDesc.Multiline = true;
degDesc.Dock = DockStyle.Fill;
degDesc.Text = degrees.undergraduate[i].description;
SizeF size = degDesc.CreateGraphics()
.MeasureString(degDesc.Text,
degDesc.Font,
degDesc.Width,
new StringFormat(0));
degDesc.Height = (int)size.Height;
degreePanel.Controls.Add(degTitle, 0, 0);
degreePanel.Controls.Add(degDesc, 0, 1);
ug_degrees.Controls.Add(degreePanel, i, row);
// Resize rows and columns (only after adding controls)
foreach (RowStyle style in ug_degrees.RowStyles) {
style.SizeType = SizeType.AutoSize;
}
// Jump to next row if current row is full
if ((i+1) % 3 == 0) {
row++;
}
Add degreePanel.Dock = DockStyle.Fill
Excuse me, a quick question:
I am using this routine to display a list of strings into a datagridview:
List<string> MyDataSource = MyList.Select(x => Path.GetFileNameWithoutExtension(x)).ToList();
AllVideosGrid.DataSource = MyDataSource.ConvertAll(x => new { Value = x });
Designer generated code:
// MyGrid
//
this.AllVideosGrid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.AllVideosGrid.Location = new System.Drawing.Point(33, 185);
this.AllVideosGrid.Name = "AllVideosGrid";
this.AllVideosGrid.RowTemplate.Height = 24;
this.AllVideosGrid.Size = new System.Drawing.Size(319, 498);
this.AllVideosGrid.TabIndex = 32;
And it gets displayed like this:
I would like rows to be resized to the datagridview size that I set initially in my designer. How can I do that?
for horizontal strecth use this:
this.AllVideosGrid.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
For vertical I think that's not possible, eventually you can set the height for each row
Like auto column height is there a function for auto row height?
The functionality is available in excel by double clicking on the row divider just like a column but I can't find the function in code.
At the moment I am having to calculate the height but there must be an easier way?
Use ExcelRow.CustomHeight = false:
sheet.Row(1).CustomHeight = false;
This will auto-size the height of the row even if you changed it before. Tested with:
DataTable dataSource = new DataTable();
dataSource.Columns.Add("Id");
dataSource.Columns.Add("Title");
dataSource.Rows.Add("1", "Title1");
using (var excel = new OfficeOpenXml.ExcelPackage())
{
var sheet = excel.Workbook.Worksheets.Add("Test");
sheet.Cells["A1"].LoadFromDataTable(dataSource, true);
sheet.Row(1).Height = 5;
sheet.Row(2).Height = 5;
sheet.Row(1).CustomHeight = false; // This will auto-size the header
excel.SaveAs(new FileInfo("Path"));
}
I'm trying to print a WPF FlowDocument. The layout needs to be in the form of 4 documents per page, laid out as follows:
Doc1 | Doc2
-------------
Doc3 | Doc4
(Sorry, I couldn't come up with a better way of illustrating the layout).
The page needs to fill, so if Doc1 & 2 are blank or just one or two characters, it still needs to print them the same size as Doc3 & 4.
The code I'm using is as follows (sorry it's long, I've tried to abridge where feasible):
PrintDialog printDialog = new PrintDialog();
if ((bool)printDialog.ShowDialog().GetValueOrDefault())
{
FlowDocument flowDocument = new FlowDocument();
flowDocument.PageHeight = printDialog.PrintableAreaHeight;
flowDocument.PageWidth = printDialog.PrintableAreaWidth;
flowDocument.PagePadding = new Thickness(25);
flowDocument.ColumnGap = 0;
flowDocument.ColumnWidth = (flowDocument.PageWidth -
flowDocument.ColumnGap -
flowDocument.PagePadding.Left -
flowDocument.PagePadding.Right);
Table myTable = new Table();
myTable.BorderThickness = new Thickness(3);
AddCols(myTable); // Add 2 cols
TableRowGroup rg = new TableRowGroup();
TableRow row = new TableRow();
AddRows(myTable); // Adds 2 rows
TableCell cell = new TableCell(new Paragraph(new Run("Doc1")));
cell.BorderThickness = new Thickness(1);
cell.BorderBrush = Brushes.Black;
// Repeat 4 times
row.Cells.Add(cell);
myTable.RowGroups.Add(rg);
doc.Blocks.Add(myTable);
....
The problem that I have is that although this does print, it doesn't try to fit it to the page as described above. Is what I am attempting possible and if so, how?
EDIT:
From looking here I believe what I actually need is a way to calculate the height of the paragraph, so that I can set the Padding property. Unfortunately the solution proposed in this link doesn't work!
Try placing the entire block in a grid so as to give it the uniform layout and then place the grid in the block and block inside your single table cell. See if this works for you -
Grid grid = new Grid();
grid.RowDefinitions.Add(new RowDefinition());
grid.RowDefinitions.Add(new RowDefinition());
grid.ColumnDefinitions.Add(new ColumnDefinition());
grid.ColumnDefinitions.Add(new ColumnDefinition());
Label text1 = new Label();
text1.Content = "Doc1";
grid.Children.Add(text1);
Grid.SetColumn(text1, 0);
Grid.SetRow(text1, 0);
Label text2 = new Label();
text1.Content = "Doc2";
grid.Children.Add(text2);
Grid.SetColumn(text2, 1);
Grid.SetRow(text2, 0);
Label text3 = new Label();
text1.Content = "Doc3";
grid.Children.Add(text3);
Grid.SetColumn(text3, 0);
Grid.SetRow(text3, 1);
Label text4 = new Label();
text1.Content = "Doc4";
grid.Children.Add(text4);
Grid.SetColumn(text4, 1);
Grid.SetRow(text4, 1);
BlockUIContainer block = new BlockUIContainer(grid);
Table table = new Table();
TableRowGroup rg = new TableRowGroup();
TableCell cell = new TableCell();
cell.Blocks.Add(block);
TableRow row = new TableRow();
row.Cells.Add(cell);
rg.Rows.Add(row);
table.RowGroups.Add(rg);
doc.Blocks.Add(table);
You could create your own custom DocumentPaginator. See here:
http://www.codeproject.com/Articles/164033/WPF-Visual-Print-Component
http://www.codeproject.com/Articles/31834/FlowDocument-pagination-with-repeating-page-header
http://www.switchonthecode.com/tutorials/wpf-printing-part-2-pagination
http://www.codeproject.com/Articles/138233/Custom-Data-Grid-Document-Paginator
Is this what you're looking for?
Convert xaml flow document to xps
question, you added the cell to the row.cell and the rowgroup to the table, but did you add the row to the rowgroup?
I use the last version of itextsharp.
I use the property HeaderRows=1 so that if there is a pagebreak, the Header rows will appear again in the next page.
Then we have the rows of the content with the border style without bottomline like this:
PdfPCell cell1 = null;
cell1 = new PdfPCell(new Phrase(string.Format("{0}", c1), fn));
cell1.Border = Rectangle.RIGHT_BORDER | Rectangle.LEFT_BORDER;
When there is a pagebreak, the line bottom of the table is not shown, which is not logical.
Even if the content rows have no bottom / top border, the PdfPTable itself should have borders (it does not have in the code in fact).
Any ideas? Thx.
I think I have been lucky, this was not easy to find.
I was looking for some event to localise the last row of the page and I found it.
You instance it like this:
PdfPTable ItemTable = new PdfPTable(7);
ItemTable.TableEvent = new LineaBottom();
The class is the following:
public class LineaBottom : IPdfPTableEvent
{
#region IPdfPTableEvent Members
void IPdfPTableEvent.TableLayout(PdfPTable table, float[][] widths, float[] heights, int headerRows, int rowStart, PdfContentByte[] canvases)
{
int columns;
Rectangle rect;
int footer = widths.Length - table.FooterRows;
int header = table.HeaderRows - table.FooterRows + 1;
int ultima = footer - 1;
if (ultima != -1)
{
columns = widths[ultima].Length - 1;
rect = new Rectangle(widths[ultima][0], heights[ultima], widths[footer - 1][columns], heights[ultima + 1]);
rect.BorderColor = BaseColor.BLACK;
rect.BorderWidth = 1;
rect.Border = Rectangle.TOP_BORDER;
canvases[PdfPTable.BASECANVAS].Rectangle(rect);
}
}
#endregion
}