Dynamic number of columns bound to a UWP datagrid (Windows Community Toolkit) - mvvm

Has anyone a sample project with a dynamic number of columns bound to a datagrid in UWP? In WPF I can get it to work with an observable collection of dynamic objects with Telerik Datagrid. But in UWP Telerik does not support dynamic objects. I have tried with the Windows Community Toolkit datagrid but failed with it too.

Dynamic number of columns bound to a UWP datagrid (Windows Community Toolkit)
derive from Samed Bejtovic's reply. We could make Dynamic number of columns in code behind with Windows Community Toolkit DataGrid. Before fill the DataGrid, we need convert the collection to DataTable, for example. The following is that load csv file and insert the data to the DataTable.
var dt = new DataTable();
bool firstLine = true;
var sr = new StreamReader("Assets\\Archive.csv");
while (sr.Peek() >= 0)
{
if (firstLine)
{
firstLine = false;
var cols = sr.ReadLine().Split(',');
foreach (string col in cols)
dt.Columns.Add(new DataColumn(col, typeof(string)));
}
else
{
var data = sr.ReadLine().Split(',');
dt.Rows.Add(data);
}
}
Then we call the FillDataGrid(dt,MyDataGrid) that could add the Columns into DataGrid base on above DataTable.
public static void FillDataGrid(DataTable table, DataGrid grid)
{
grid.Columns.Clear();
for (int i = 0; i < table.Columns.Count; i++)
{
grid.Columns.Add(new DataGridTextColumn()
{
Header = table.Columns[i].ColumnName,
Binding = new Binding { Path = new PropertyPath("[" + i.ToString() + "]") }
});
}
var collection = new ObservableCollection<object>();
foreach (DataRow row in table.Rows)
{
collection.Add(row.ItemArray);
}
grid.ItemsSource = collection;
}

DataCollection = new ObservableCollection<dynamic>();
while (reader.Read())
{
string project = reader.GetString(0);
decimal number = reader.GetDecimal(1);
DataCollection.Add(new DataSummary(project, number));
}
Datagrid supports auto generated columns. Set the items source to the collection.
https://www.reddit.com/r/UWP/comments/djzcqj/display_datatable_as_datagrid/?utm_source=share&utm_medium=web2x

Related

How to remove the extra page at the end of a word document which created during mail merge

I have written a piece of code to create a word document by mail merge using Syncfusion (Assembly Syncfusion.DocIO.Portable, Version=17.1200.0.50,), Angular 7+ and .NET Core. Please see the code below.
private MemoryStream MergePaymentPlanInstalmentsScheduleToPdf(List<PaymentPlanInstalmentReportModel>
PaymentPlanDetails, byte[] templateFileBytes)
{
if (templateFileBytes == null || templateFileBytes.Length == 0)
{
return null;
}
var templateStream = new MemoryStream(templateFileBytes);
var pdfStream = new MemoryStream();
WordDocument mergeDocument = null;
using (mergeDocument = new WordDocument(templateStream, FormatType.Docx))
{
if (mergeDocument != null)
{
var mergeList = new List<PaymentPlanInstalmentScheduleMailMergeModel>();
var obj = new PaymentPlanInstalmentScheduleMailMergeModel();
obj.Applicants = 0;
if (PaymentPlanDetails != null && PaymentPlanDetails.Any()) {
var applicantCount = PaymentPlanDetails.GroupBy(a => a.StudentID)
.Select(s => new
{
StudentID = s.Key,
Count = s.Select(a => a.StudentID).Distinct().Count()
});
obj.Applicants = applicantCount?.Count() > 0 ? applicantCount.Count() : 0;
}
mergeList.Add(obj);
var reportDataSource = new MailMergeDataTable("Report", mergeList);
var tableDataSource = new MailMergeDataTable("PaymentPlanDetails", PaymentPlanDetails);
List<DictionaryEntry> commands = new List<DictionaryEntry>();
commands.Add(new DictionaryEntry("Report", ""));
commands.Add(new DictionaryEntry("PaymentPlanDetails", ""));
MailMergeDataSet ds = new MailMergeDataSet();
ds.Add(reportDataSource);
ds.Add(tableDataSource);
mergeDocument.MailMerge.ExecuteNestedGroup(ds, commands);
mergeDocument.UpdateDocumentFields();
using (var converter = new DocIORenderer())
{
using (var pdfDocument = converter.ConvertToPDF(mergeDocument))
{
pdfDocument.Save(pdfStream);
pdfDocument.Close();
}
}
mergeDocument.Close();
}
}
return pdfStream;
}
Once the document is generated, I notice there is a blank page (with the footer) at the end. I searched for a solution on the internet over and over again, but I was not able to find a solution. According to experts, I have done the initial checks such as making sure that the initial word template file has no page breaks, etc.
I am wondering if there is something that I can do from my code to remove any extra page breaks or anything like that, which can cause this.
Any other suggested solution for this, even including MS Word document modifications also appreciated.
Please refer the below documentation link to remove empty page at the end of Word document using Syncfusion Word library (Essential DocIO).
https://www.syncfusion.com/kb/10724/how-to-remove-empty-page-at-end-of-word-document
Please reuse the code snippet before converting Word to PDF in your sample application.
Note: I work for Syncfusion.

Nested Table issue with iText in .net

I use iText 7.0.4.0 with my .net application to generate pdfs. But inner tables overflow when the text is long.
Outer table has 10 columns with green border and seems it has rendered fine as per the image below. Each Outer table cell contains one table with one cell inside it.But Inner Table cell has overflown when the paragraph text is large.
I use iText in a large Forms building product. Hence I've recreated the issue with simple scenario and the code is given below. Please note that the number of columns are not fixed in real usage.
Could anyone please show me the correct path to achieve this?
Here is the C# Code
private Table OuterTable()
{
var columns = GetTableColumnWidth(10);
var outerTable = new Table(columns, true);
outerTable.SetWidthPercent(100);
for (int index = 0; index < columns.Length; index++)
{
Cell outerTableCell = new Cell();
Table innerTable = new Table(new float[] { 100 });
innerTable.SetWidthPercent(100);
Cell innerTableCell = new Cell();
Paragraph paragraph = new Paragraph("ABCDEFGHIJKL").AddStyle(_fieldValueStyle);
innerTableCell.Add(paragraph);
innerTable.AddCell(innerTableCell);
outerTableCell.Add(innerTable);
outerTable.AddCell(outerTableCell);
innerTableCell.SetBorder(new SolidBorder(Color.RED, 2));
innerTableCell.SetBorderRight(new SolidBorder(Color.BLUE, 2));
outerTableCell.SetBorder(new SolidBorder(Color.GREEN, 2));
}
return outerTable;
}
Thanks mkl for spending your valuable time. I solved my issue with your idea of 'no inner tables'. This is not how to solve the issue of nested tables mentioned in the question but another way of achieving the result.
I've used "\n" in the paragraph to achieve what I want. Here is the output and the code.
private Table OuterTable()
{
var columns = GetTableColumnWidth(10);
var outerTable = new Table(columns, true);
outerTable.SetWidthPercent(100);
for (int index = 0; index < columns.Length; index++)
{
Cell outerTableCell = new Cell();
outerTableCell.Add(GetContent());
outerTable.AddCell(outerTableCell);
}
return outerTable;
}
private Paragraph GetContent()
{
int maxIndex = 3;
Paragraph paragraph = new Paragraph();
for (int index = 0; index < maxIndex; index++)
{
paragraph.Add(index + " - ABCDEFGHIJKL \n").AddStyle(_fieldValueStyle);
}
return paragraph;
}

How to add rows to TableView without having any data model

I'm fairly new to javafx, so please bear with me if my question is unclear. I've a TableView which need to be populated using an ObservableList.
The code below populates my "data" with the arraylists generated out of the Map, which in turn is used to add rows to my table.
TableView<ArrayList> table = new TableView<>();
ObservableList<ArrayList> data = FXCollections.observableArrayList();
for(int i=0;i<listSelectedVerticesIds.size();i++){
ArrayList<String> tempString = new ArrayList<>();
for(Map.Entry<String,String> temp2 : mapVertex.get(listSelectedVerticesIds.get(i)).entrySet()){
tempString.add(temp2.getValue());
}
data.add(tempString);
}
table.setItems(data);
However, I do not see the table populated with the list in "data". I'm guessing this is because there is no data binding (using setCellValueFactory). However, as you can see I dont have a data model class. All of my data comes from the Map as strings which I would like to populate in my tableview.
Please suggest.
Here is a simple way to do it that works great. You don't need a data structure to populate a table. You only see that because that's what most examples show. It is an extremely common use case to populate a table from a database or a file. I don't understand why this is so hard to find examples for. Well, hope this helps.
private TableView<ObservableList<StringProperty>> table = new TableView<>();
private ArrayList<String> myList = new ArrayList<>();
private void updateTableRow() {
for (int row = 0; row < numberOfRows; row++) {
ObservableList<StringProperty> data = FXCollections.observableArrayList();
for (int column = 0; column < numberOfColumns; column++) {
data.add(column, new SimpleStringProperty(myList.get(row + (column * numberOfRows))));
}
table.getItems().add(data);
}
}

Updating column in tableviwer

I have retrieved data from database and i am able to show it in Table of the Table Viewer but my task is on click of a row the data should be appear in another form from where i can edit it and on click of update the view should be updated with the new values.I am using viewer.addSelectionChangedListener to retrieve the selected row but i am not getting how to update the table .Please suggest me few ideas
I have written the below code in the constructor of my class so whenever object is created Table is generated and l1 is list of data which i am passing to another UI
input[i] = new MyModel(persons[i].getDateOfRegistration(), persons[i].getFirstName(),
persons[i].getMiddleName(), persons[i].getLastName(), persons[i].getGender(),
persons[i].getDob(), persons[i].getContactNumber(), persons[i].getMaritalStatus(),
persons[i].getAddress(), persons[i].getCountry(), persons[i].getBloodGroup(),
persons[i].getInsuranceDetails().getPolicyHolderName(),
persons[i].getInsuranceDetails().getPolicyNumber(),
persons[i].getInsuranceDetails().getSubscriberName(),
persons[i].getInsuranceDetails().getRelationshipToPatient());
viewer.setInput(input);
table.setHeaderVisible(true);
table.setLinesVisible(true);
GridData gridData = new GridData();
gridData.verticalAlignment = GridData.FILL;
gridData.horizontalSpan = 2;
gridData.grabExcessHorizontalSpace = true;
gridData.grabExcessVerticalSpace = true;
gridData.horizontalAlignment = GridData.FILL;
viewer.getControl().setLayoutData(gridData);
viewer.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
IStructuredSelection selection = (IStructuredSelection) event.getSelection();
StringBuffer sb = new StringBuffer("Selection - ");
int j = 0;
String[] s;
for (Iterator iterator = selection.iterator(); iterator.hasNext();) {
sb.append(iterator.next() + ", ");
System.out.println("Testing::" + sb);
}
System.out.println(sb);
String result[] = new String[18];
List l1 = new ArrayList(100);
String[] parts = sb.toString().split("=");
for (int i = 0; i < parts.length; i++) {
System.out.println("s" + parts[i]);
String[] s1 = parts[i].split(",");
l1.add(s1[0]);
}
SWTPatientRegistrationUpdatePageEventView swtPatientRegistrationUpdatePageEventView = new SWTPatientRegistrationUpdatePageEventView();
swtPatientRegistrationUpdatePageEventView.openParentUpdateShell(l1);
// viewer.refresh();
//flag=false;
//refreshingData(list);
}
});
Make sure we will follow table viewer MVC architecture all the time. Steps we can do to resolve your issue isas follow:
Create proper datastructure(Model Class) to hold the data. and use the same in array which you set in viewer.setInput()
When you click/double click on table row, fetch the data and save it in datastructure created(with new object).
Pass that data structure to your form dialog.
when you are done with update in form. Fill the updated data in new Model object again.
And after form close, pass that model object back to parent.
updated the corresponding array element with object received from Form Dialog and just refresh the tableviewer.
Please let me know if you need some code module. Thanks

Export MS Word Document pages to Images

I want to export MS word(docx/doc) document pages to Image(jpeg/png).
I am doing same for presentation(pptx/ppt) using office interop export api for each slide, but didn't found corresponding API for word.
Need suggestion for API/alternate approach for achieving this.
Based on this similar question: "Saving a word document as an image" you could do something like this:
const string basePath = #"C:\Users\SomeUser\SomePath\";
var docPath = Path.Combine(basePath, "documentA.docx");
var app = new Application()
{
Visible = true
};
var doc = app.Documents.Open(docPath);
foreach (Window window in doc.Windows)
{
foreach (Pane pane in window.Panes)
{
for (var i = 1; i <= pane.Pages.Count; i++)
{
var page = pane.Pages[i];
var bits = page.EnhMetaFileBits;
var target = Path.Combine(basePath, string.Format("page-no-{0}", i));
using (var ms = new MemoryStream(bits))
{
var image = Image.FromStream(ms);
var pngTarget = Path.ChangeExtension(target, "png");
image.Save(pngTarget, ImageFormat.Png);
}
}
}
}
app.Quit();
Basically, I'm using the Page.EhmMetaFileBits property which, according to the documentation:
Returns a Object that represents a picture representation of how a
page of text appears.
... and based on that, I create an image and save it to the disk.