So,
In my WPF application, I want my users to be able to open previews of invoices, so that they may either verify or discard them. I am letting them check rows (each row representing a invoice) in a DataGridCheckBoxColumn in my DataGrid, then clicking a button (which runs my CreateInvoicePreview() method, see bottom of post), having all of the invoice previews be opened in new windows (one window for each invoice).
Well.. What happens now, is: User checks InvoiceA and InvoiceB. Two invoices are opened, but they are the same: InvoiceC. The correct amount of invoices are always opened, but not the correct instance. If I open the temp folder specified in my file path, I see that all invoices in the datagrid has been saved: InvoiceA through InvoiceJ.
Let me take you through the code.
This is the method that creates that builds and saves the actual PDF's, which the WebView2 control uses as source, so that it can display them in-app. It is heavily abbreviated.
I have kept the structure with the nested foreach loops in case that is relevant.
public void CreatePreviewInvoice() {
/* SQL SERVER CODE
* SQL SERVER CODE
* SQL SERVER CODE */
List<PaidTrip> paidTrips = PaidTrips.ToList();
tripsGroupedByCompany = paidTrips.GroupBy(pt => pt.LicenseHolderID);
foreach (IGrouping<string, PaidTrip> companyGroup in tripsGroupedByCompany) {
/* SQL SERVER CODE
* SQL SERVER CODE
* SQL SERVER CODE */
List<LicenseHolder> licenseHolders = LicenseHolders.ToList();
IEnumerable<IGrouping<string, PaidTrip>> groupedByVehicle = companyGroup.GroupBy(n => n.VehicleID);
foreach (IGrouping<string, PaidTrip> vehicleGroup in groupedByVehicle) {
// Iterating over all data pertaining to each vehicle
foreach (PaidTrip trip in vehicleGroup) {
}
try {
string userName = System.Security.Principal.WindowsIdentity.GetCurrent().Name.Split('\\')[1];
string fileName = $"FORHÅNDSVISNING - MÅ IKKE SENDES! {LicenseHolderID + "_" + "Faktura_" + InvoiceID}.pdf";
string filePath = $@"C:\Users\{userName}\AppData\Local\Temp\";
PdfFilePath = $"{filePath}{fileName}";
//if (LicenseHolderID == PreviewInvoiceViewModel.SelectedRow.LicenseHolderID) {
document.Save($"{PdfFilePath}");
//} else {
// return;
//}
} catch (Exception ex) {
MessageBox.Show(ex.Message);
}
}
}
As you see, towards the end of the method I have commented out a bit of code, which was me trying to implement a way to filter based on the checked rows only. It did not work.
This is the XAML for the WebView2:
<Wpf:WebView2
x:Name="wv_preview_invoice" Loaded="{s:Action CreatePreviewInvoice}"
Height="997" Width="702" Canvas.Left="20" Canvas.Top="71"
Source="{Binding PdfFilePath}"></Wpf:WebView2>
PdfFilePath is a property, which is referenced within the method above.
It's given a value within the method, and when Source (for the WebView2) is called, it is able to get the value from PdfFilePath, and thus display the PDF.
But as I said initially, it just creates X amount of instances/windows of the same invoice. Always the same one, because of in what order they are queried from the database.
And finally, here is the method that run when they click whichever invoices they want to preview, it's to open the new window with the WebView2 control:
public void PreviewInvoices() {
bool success = false;
foreach (PaidTrip item in PaidTrips) {
if (item.IsChecked == true) {
ShowPreviewInvoiceDetailed(item);
success = true;
}
}
if (!success) {
MessageBox.Show("You must chose an invoice to preview first.");
}
}
The method that opens the next window where the WebView2 is, looks like this:
public void ShowPreviewInvoiceDetailed() {
PreviewInvoiceDetailedViewModel viewModel = new(windowManager);
windowManager.ShowWindow(viewModel);
}
What part (or several parts) of the picture am I missing?