FlowDocument BreakPageBefore property not working on Table Block - c#

So I'm dynamically creating a FlowDocument by using code (based on this MSDN article on How to build a table programatically).
The FlowDocument contains a number of blocks including paragraphs and tables. The tables being generated are of varying sizes and some are nested amongst other blocks. If a table can't fit on the remaining space on a page, I want to start that table at the beginning of the next page.
I am doing this by recording the current page when creating a particular block and then when the table has been finished, if I am on a new page, I set the BreakPageBefore property to true. Something like this:
foreach (var item in Data)
{
Table table = new Table();
flowDoc.Blocks.Add(table);
paginatorSource.DocumentPaginator.ComputePageCount();
pagecount = paginatorSource.DocumentPaginator.PageCount;
//do some work populating the table details...
TableColumn t = new TableColumn(); //etc...
paginatorSource.DocumentPaginator.ComputePageCount();
int newPagecount = paginatorSource.DocumentPaginator.PageCount;
if (newPagecount != pagecount)
{
//The table has spanned a new page so set the page break!
table.BreakPageBefore = true;
}
}
But this doesn't appear to work. However, if I wrap the table in a Section and set the BreakPageBefore on the section, it works fine. Also, If I have a Paragraph just before the table, I can set the BreakPageBefore on the Paragraph and that also works fine.
I have tried creating a simple FlowDocument that just has a bunch of repeating tables and that doesn't make any difference and I still have to wrap them in a Section.
They all inherit from Block So why won't it work on the Table directly?

Related

ClosedXml C# Overwriting existing style of excel file when new data are inserted for a range

I am trying to insert new data, but whenever I put new data then existing styles of my template are overwritten making them default ones. The background style of cells is replaced to default white color.
public IWorkbookBuilderSheetOperation Insert<T>(IEnumerable<T[]> rows, int firstCellRow, int firstCellColumn)
{
_currentSheet.IsSelected();
var lastCell = CalculateLastCell(rows, firstCellRow, firstCellColumn);
var range = _currentSheet!.Range(firstCellRow, firstCellColumn, lastCell.lastCellRow, lastCell.lastCellColumn);
_ = range.Cell(1, 1).InsertData(rows);
return this;
}
How can I keep existing styles when I read a template file and modify it.
If you can use an Excel table, it will keep a uniform look no matter how many rows you insert using the methods on IXLTable.
If you can't use a table and you need to keep using cell.InsertData(), then you could still manually copy the .Style of the old range to where you want it.

Migradoc - Tables Side by Side - not using Tables within Tables

I am using Migradoc and wish to replicate a table structure as follows:
What I really DON'T want to do is add each table into a cell of a larger table with 2 columns and 2 rows... Mainly because i) the number of tables generated can vary so it needs to be more dynamic and ii) Adding tables within tables can cause issues when spilling across to the next page.
What I had initially hoped is that I could just keep adding each new table to a TextFrame and the tables will be added horizontally and wrap to the next page if the next table wouldn't fit... Of course, not that straight forward. So far the closest I have come to even seeing a Table next to another one is with the following:
TextFrame newTF = new TextFrame
{
Width = Unit.FromPoint(200)
};
WrapFormat wf = new WrapFormat();
wf.Style = WrapStyle.Through;
newTF.WrapFormat = wf;
newTF.Add(newTable.Clone());
this.document.LastSection.Add(newTF);
TextFrame newTF2 = new TextFrame
{
Width = Unit.FromPoint(200)
};
WrapFormat wf2 = new WrapFormat();
wf2.Style = WrapStyle.Through;
newTF2.RelativeHorizontal = RelativeHorizontal.Page;
newTF2.RelativeVertical = RelativeVertical.Paragraph;
newTF2.Left = ShapePosition.Right;
newTF2.WrapFormat = wf2;
newTF2.Add(newTable.Clone());
this.document.LastSection.Add(newTF2);
However this is very static and would require a new definition for each TextFrame. Plus, the layout doesn't look amazing as the second table ignores any margins set out in the page.
If what I am asking is at all possible, am I even on the correct path? I have been looking into this all morning and am starting to feel my options sllipping away! I would have thought this would be a big requirement for a lot of Migradoc users so am surprised to find it is tricky to do? Unless I am just missing something silly of course.
Another option: create a table with 5 columns and set table borders to make it look like 2 tables with 2 columns each.
Depending on the data you add to the tables it might be better to use a table row for each line of text or have all text lines in a single row.
From your picture I assume that using a table with 2 columns and 1 row, each cell containing a table, would work, too, provided the visible tables are small enough to fit a single page.

Assigning a different ViewSource in WPF

I'm experimenting with C#/.net/WPF all for the first time. I've created a project and set up a datasource (just a table with some sample data) and created two tableadapters named Prods and Prods1 - the latter has a filter applied in the query to return slightly different results. I've dropped both tables on my form and both dutifully display their respective data.
I thought I would then swap the data source for each. So the default generated Window_Loaded:
MSDSTest.prodtestDataSet prodtestDataSet = ((MSDSTest.prodtestDataSet)(this.FindResource("prodtestDataSet")));
// Load data into the table Prods. You can modify this code as needed.
MSDSTest.prodtestDataSetTableAdapters.ProdsTableAdapter prodtestDataSetProdsTableAdapter = new MSDSTest.prodtestDataSetTableAdapters.ProdsTableAdapter();
prodtestDataSetProdsTableAdapter.Fill(prodtestDataSet.Prods);
System.Windows.Data.CollectionViewSource prodsViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("prodsViewSource")));
prodsViewSource.View.MoveCurrentToFirst();
// Load data into the table Prods1. You can modify this code as needed.
MSDSTest.prodtestDataSetTableAdapters.Prods1TableAdapter prodtestDataSetProds1TableAdapter = new MSDSTest.prodtestDataSetTableAdapters.Prods1TableAdapter();
prodtestDataSetProds1TableAdapter.Fill(prodtestDataSet.Prods1);
System.Windows.Data.CollectionViewSource prods1ViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("prods1ViewSource")));
prods1ViewSource.View.MoveCurrentToFirst();
I now want to make the first data grid (prodsViewSource) instead display the data for the second table, and ignore the second table entirely. So, I changed that as follows:
MSDSTest.prodtestDataSet prodtestDataSet = ((MSDSTest.prodtestDataSet)(this.FindResource("prodtestDataSet")));
// Load data into the table Prods. You can modify this code as needed.
MSDSTest.prodtestDataSetTableAdapters.Prods1TableAdapter prodtestDataSetProdsTableAdapter = new MSDSTest.prodtestDataSetTableAdapters.Prods1TableAdapter();
prodtestDataSetProdsTableAdapter.Fill(prodtestDataSet.Prods1);
System.Windows.Data.CollectionViewSource prodsViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("prodsViewSource")));
prodsViewSource.View.MoveCurrentToFirst();
With the second block having been commented out.
I must be missing something fundamental - what I think I'm doing is redefining the prodtestDataSetProdsTableAddapter variable to use an instance of the prods1 table adapter, and then using that to populate the prodsViewSource grid on the form, but I end up with a blank. Where's my error?
...
Well, I posted this after beating my head against it for an hour and, minutes later, realized the FAR easier thing to do is to just change the datacontext property of the grid in question.
I would still like to understand why doing it the vastly more complicated-bordering-on-Rube-Goldbergian way didn't work, though, so if anyone can explain that, it would still be welcome.

Interop - Setting a range for an Excel chart to an entire row

How do I set the source data of an excel interop chart to several entire rows?
I have a .csv file that is created by my program to display some results that are produced. For the sake of simplicity let's say these results and chart are displayed like this: (which is exactly how I want it to be)
Now the problem I am having is that the number of people is variable. So I really need to access the entire rows data.
Right now, I am doing this:
var range = worksheet.get_range("A1","D3");
xlExcel.ActiveChart.SetSourceData(range);
and this works great if you only have three Persons, but I need to access the entire row of data.
So to restate my question, how can I set the source data of my chart to several entire rows?
I tried looking here but couldn't seem to make that work with rows instead of columns.
var range = worksheet.get_range("A1").CurrentRegion;
xlExcel.ActiveChart.SetSourceData(range);
EDIT: I am assuming that the cells in the data region won't be blank.
To test this,
1) place cursor on cell A1
2) press F5
3) click on "Special"
4) choose "Current Region" as option
5) click "OK"
This will select the cells surrounding A1 which are filled, which I believe is what you are looking for.
The translation of that in VBA code points to CurrentRegion property. I think, that should work.
Check Out the option Range.EntireRow I'm not 100% on how to expand that to a single range containing 3 entire rows, but it shouldn't be that difficult to accomplish.
Another thing you can do is scan to get the actual maximum column index you need (this is assuming that there are guaranteed to be no gaps in the names), then use that index as you declare your range.
Add Code
int c = 2;//column b
while(true)
{
if (String.IsNullOrEmpty(worksheet.GetRange(1,c).Value2))
{
c--;
break;
}
c++;
}
Take a column from A to D that you're sure has no empty cells.
Do some loop to find the first empty one in that column and it will be one after the last.
Range Cell = SHeet.Range["A1"]; //or another column you're sure there's no empty data
int LineOffset = 0;
while (Cell.Offset[LineOffset, 0].Value != "") //maybe you should cast the left side to string, not sure.
{
LineOffset++;
}
int LastLine = LineOffset - 1;
Then you can get Range[Sheet.Cells[1,1], Sheet.Cells[LastLine, 4]]
Out of the box here, but why not transpose the data? Three columns for Name, Height, Weight. Convert this from an ordinary range to a Table.
When any formula, including a chart's SERIES formula references a column of a table, it always references that column, no matter how long the table gets. Add another person (another row) and the chart displays the data with the added person. Remove a few people, and the chart adjusts without leaving blanks at the end.
This is illustrated in my tutorial, Easy Dynamic Charts Using Lists or Tables.

Word 2007: Duplicate a table with content control from one page to another

Is there a way to clone table with predefined style, fonts, content control etc. from one page to another page so that i can fill in different data in different tales.
so for instance I wwould have, lets say, a table that shows Name, Age, Address of one person in one table. then the next page has the same table style but the information is different.
Is this possible? I found a way to clone rows/columns but not entire table.
I am using C# with OpenXML SDK 2.0. Any help in this subject would be much appreciated.
Thanks in anticipation.
regards
this article may help
foreach (var order in customerOrderHistory)
{
TableRow rowCopy = (TableRow)theRow.CloneNode(true);
rowCopy.Descendants<TableCell>().ElementAt(0).Append(new Paragraph
(new Run (new Text(order.Contact.ToString()))));
rowCopy.Descendants<TableCell>().ElementAt(1).Append(new Paragraph
(new Run (new Text(order.NameOfProduct.ToString()))));
rowCopy.Descendants<TableCell>().ElementAt(2).Append(new Paragraph
(new Run (new Text(order.Amount.ToString()))));
theTable.AppendChild(rowCopy);
}

Categories

Resources