nested tables in aspose - c#

I need to divide two cells in adjacent columns into X equal cells horizontally. I am given a DocumentBuilder, pointing to the cell. I decided that I can insert a separate table into the cell:
var table = builder.StartTable();
builder.InsertCell();
table.AutoFit(AutoFitBehavior.AutoFitToWindow);
builder.Write("1");
builder.EndRow();
builder.InsertCell();
builder.Write("2");
builder.EndRow();
builder.EndTable();
But still, there is a margin on the sides of the inner table:
(ignore the left cell being splitted by horizontal thick line)
I googled that table.AutoFit(AutoFitBehavior.AutoFitToWindow); should solve the problem, but it doesn't. What am I supposed to do, to get desired output:

I managed to split the cell vertically, by setting all other cells in a row cell.CellFormat.VerticalMerge = CellMerge.First, then adding X - 1 rows, in which cells are cell.CellFormat.VerticalMerge = CellMerge.Previous, except cells in columns to de divided.

Related

DataGridView - extra grey space after last row

I have a DataGridView with two columns. After the last row I have some gray space. It is exactly the same problem here but it is unsolved DataGridView showing some extra space after last row
How can I get rid of this extra gray space on the bottom?
Edit: Here you can download preview that I am talking about:
https://github.com/pr0s3q/DataGridViewError
Unwanted grey space
The problem got fixed by changing datagridview height.
My images have 85px height, so I need to fit specific number of them (i.e. 4, not 3.5)
So 85x4 = 340, adding inner margins, I need to have 347px height in order to not see this ugly gray space

MigraDoc - Table Border but no Cell/Row/Column Borders

I am struggling to implement what seems should be something straight forward, but having not much luck. I need a MigraDoc table to render with just the Table border, excluding all cells in between:
I have followed the remarks on this post:
How do you add a border around a table in MigraDoc?
Useful information but I havent been able to implement a full fix from it?
I have the following code run just before the table is added to the section:
table.Borders.Visible = true;
for (int i = 0; i < table.Rows.Count - 2; i++)
{
table.Rows[i].Borders.Bottom.Visible = false;
}
Which at first seemed like it did the job... until I come across a table that follows onto the next page... The bottom row border is obviously only rendered for the very bottom row and does not account for PageBreaks mid-table.
Surely there must be a better way of doing this?
EDIT: I appreciate this is somewhat of an old question, but just incase anyone ends up here looking for an answer...
Try using the SetEdge option. There's two ways you could do it, depending on whether you know how many table rows or columns you're going to have (static content), or you don't know yet (dynamic content).
Option 1: Static table content
Set your table up first, so all the columns, cells and rows exist, then add an edge border to your table with
table.SetEdge(a, b, x, y, Edge.Box, BorderStyle.Single, 1, Colors.Black);
The first four numbers a, b, x, y indicate which of the table cells you want to add a borders to, the first two numbers are the top left column then row (in your case to border the whole table, this should be 0, 0) and the second two numbers are the bottom right corner column then row (as per your example this is 3, 4, assuming the heading is a heading row).
After Edge.Box, the options are border style, border width, border color.
You can then add any extra individual borders per cell or row after as normal, so to add a border at the bottom of your header row as per your example...
headerRow.Borders.Bottom.Width = 0.2;
headerRow.Borders.Bottom.Color = Colors.Black;
Option 2: Dynamic table content
If you don't know how many rows or columns are in your table becuase the content is dynamic, the first four numbers in SetEdge could be set with this.table.Columns.Countand this.table.Rows.Count - for example :
table.SetEdge(0, 0, this.table.Columns.Count, this.table.Rows.Count, Edge.Box, BorderStyle.Single, 1, Colors.Black);
References
For more info, see this post:
https://forum.pdfsharp.net/viewtopic.php?f=2&t=3598
And it's also here in the MigraDoc Example (search for SetEdge):
http://pdfsharp.net/wiki/HelloMigraDoc-sample.ashx

C#: DataGridView's extra space on right-hand side and scrollbar

I have a DataGridView control, and the number of columns changes depending on the input from the user every 10 minutes.
What needs to be achieved is:
The DataGridView needs to show all columns without a horizontal scrollbar unless it affects the readability of any cell contents. If it starts hiding a cell content, a horizontal scrollbar needs to appear.
Regardless of how many columns are currently shown, and regardless of whether the horizontal scrollbar is shown or not, the right-hand side of the DataGridView's data must be filled so there is no unused space.
Regardless of the length of the cell contents, all of the column widths need to be the same. (A cell can have an integer from 10 up to 9999)
All of these 3 requirements need to be satisfied at the same time, but if I try to meet one requirement, the other(s) falls apart. I know for sure that there are always at least 16 columns no matter what. It is really up to the user if there will be more columns or not.
Can someone tell me what is wrong with the following?
int countVisible = 0; //Count the number of columns displayed
foreach(DataGridViewColumn col in myDGV.Columns)
if(col.Visible) countVisible++;
//By default, use Fill mode
DataGridViewAutoSizeColumnMode mode = DataGridViewAutoSizeColumnMode.Fill;
//I am trying to show up to 20 columns without a scrollbar
//A horizontal scrollbar required for more than 20 columns
//If there are more than 20 columns, use DisplayedCells mode
if(countVisible > 20)
mode = DataGridViewAutoSizeColumnMode.DisplayedCells;
//Apply the mode to all columns
for(int i = 0; i < myDGV.Columns.Count; i++)
myDGV.Columns[i].AutoSizeMode = mode;
This code works if the number of columns is less than a certain value, but in the case of greater than the certain value, it shrinks the width of columns that only have 2-digit numbers in all rows, and it violates the requirement #3. By shrinking some column widths, it creates extra space on the right-hand side, and it violates the requirement #2.
I am so lost and stuck. Can someone please help? Any advice will be greatly appreciated.
The requirements appear to be somewhat obscure to me. One issue would be requirement 3…
”3. Regardless of the length of the cell contents, all of the column widths need to be the same. (A cell can have an integer from 10 up to 9999)” …
If ALL columns have to be the same width and at least ONE (1) cell has a value of “9999” then ALL the columns will be this width regardless of how many digits it has.
It does appear a requirement is to have all the data display in a cell, in addition… have all the columns the same width. This will require going through each cell and find the cell with the largest width to display all its data and make ALL columns this width to keep with the previous requirement.
The point being, that requiring all the columns to be the same size AND make sure ALL the contents of every cell is displayed leaves little to question… Each column will have to be the width of the largest value. Any other situation will break one of the requirements.
Assuming the above is correct, the other requirement
”2. Regardless of how many columns are currently shown, and regardless of whether the horizontal scrollbar is shown or not, the right-hand side of the DataGridView's data must be filled so there is no unused space.” …
I am confident YOU will have to control this. Unfortunately, the grids column “Fill” property will gladly cram a hundred columns into a small space. This suggest that you will have to get the grids displayed width, count how many columns there are, find the width for the columns and check to see if it fits in the grids display.
This implies a MINIMUM value for a columns width. If each columns width is set to a minimum value AND the total width from all columns is greater than the grids width, then obviously you are going to need a horizontal scroll bar.
Given this, to find the total width of all the columns is easy enough. If this value is greater than the grids width, then the horizontal scroll bar will appear automatically, nothing else needs to be done unless you want to avoid the possible splitting of a column which would most likely involve resizing the grid. If the total width of the columns is less than the grids width… then simply set the columns to fill. Below is an example.
A global variable minWidth is used to ensure all columns are at least this value. This is a value you could get some other way; in this case, its purpose is to set a columns minimum width.
First, a check is made to see if the width is less than the minimum and if so set it to the minimum. Next, set each columns width to the given value. Finally check to see if the total width of all columns is greater than the grids width. If the columns will not fit in the grids width then simply set the grid to DisplayedCells and the horizontal scroll bar will pop up. .If the columns do fit, then simply set the grids AutoColumnSizeMode to Fill. Hope this helps.
int minWidth = 40;
private int YourMethodToGetColumnWidth() {
return myDGV.Width / myDGV.Columns.Count;
}
private void SetColumnWidths() {
int columnWidth = YourMethodToGetColumnWidth();
if (columnWidth < minWidth)
columnWidth = minWidth;
foreach (DataGridViewColumn col in myDGV.Columns)
col.Width = columnWidth;
int allColumnsWidth = columnWidth * myDGV.Columns.Count;
if (allColumnsWidth > myDGV.Width) {
myDGV.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells;
}
else {
myDGV.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
}
}
I read your interesting question yesterday. Thinking about it, in my opinion the best solution is to get rid of AutoSizeMode at all and create a variable ColMinWidth for a minimum width of a column. Then get DataGridView.Width and divide it by the number of required columns (with a little tweak, perhaps 2px less). If the calculated width of the column is greater then ColMinWidth, then this will be a width of the column, otherwise use ColMinWidth.
Finally set that width to all columns.
I think that this is minimal solution and unlike AutoSize with hidden catches, reliable.

autofit column width to contents in word automation

Using Microsoft Interop for word, after adding a table to the document, how can the column width be set for all columns so that it fits the largest item there? For example, if the column header is only two letters, and each cell underneath is only one digit, the column should only be about a centimeter wide.
If you only have one table in your document, you would use something like this (where oDoc is your active document.)
oDoc.Tables(0).AllowAutoFit = True;
oDoc.Tables(0).AutoFitBehavior(Word.WdAutoFitBehavior.wdAutoFitContent);
If you have more than one table, you'd want to choose the index of the one you wish to update or loop through them.
In the Word object model AutoFit is what the feature is called that allows (or doesn't allow) table columns to resize to fit the content, the width of the window/page or prevents them from resizing automatically.
To force the table columns to resize to fit their content:
tbl.AutoFitBehavior(Word.WdAutoFitBehavior.wdAutoFitContent);
To change the width of a single column to fit to the content:
tbl.Columns[index].AutoFit();
This can also be done for all columns:
tlb.Columns.AutoFit();

PowerPoint 2007 Tables: Identify Merged Cells

How do I identify merged cells in PowerPoint 2007? Is there anyway we could find a particular cell is merged.
In 2003 we tried to access the Fill.Visible property of a cell and when it throws an error we can identify the cell as a merged cell. How do we achive this in 2007?
It's tough. However, the best way I've found is to check the width of the cell. This code isn't the best as it catches every cell, but it could be a starting point for you:
Dim r As Row
Dim co As Column
Dim c As Cell
For Each co In tbl.Columns
For Each c In co.Cells
If c.Shape.Width <> co.Width Then
Debug.Print "Is merged cell"
End If
Next
Next
In a 2x2 table where cells 2.1 and 2.2 are merged (i.e. the second row is now one cell), this will print "Is merged cell" twice because internally the table still maintains cells 2.1 and 2.2. But it's a starting point as stated...
I think much better would be to compare c1.Left == c2.Left && c1.Top == c2.Top. This would mean that the 2 cells are merged. To traverse all the cells just once I just remove "duplicates" using LINQ's Distinct and custom Comparer.
Cells that are merged together will have the same cell.Shape.Name. Unfortunately while this works on PowerPoint 2003, you get NotImplementedException when asking for the name of these Shapes on PowerPoint 2007. I don't know about later versions.
Recently, I dug into the mystery of merged cells in the PowerPoint table.
I ended up figuring out my own methods to deal with merged cells.
Please refer to the following link:
https://stackoverflow.com/a/74563860/6354194
There are a few useful functions for merged cells:
test if the cell is merged
test if the cell is the first(Top-Left) cell of the merged area
get the index no. of the cells in the merged area, top to bottom, left to right
get the width and height of merged area
test if the given cells are within a merged area

Categories

Resources