My app is creating from some user input, some unique numbers and displaying those as QR codes, so that they can be printed out.
This is the function where I'm facing an issue.
private void Button_Click(object sender, RoutedEventArgs e)
{
listBox10.Visibility = Visibility.Collapsed;
PrintGrid.Visibility = Visibility.Visible;
GenerateUniqueNumber_v2.PrintTemplate printTemplate = new GenerateUniqueNumber_v2.PrintTemplate();
// Create a temporary ListBox to hold items for printing
ListBox tempListBox = new ListBox();
// Create a list to hold the filled templates
List<FrameworkElement> filledTemplates = new List<FrameworkElement>();
// Iterate over the items in the ListBox
for (int i = 0; i < listBox10.Items.Count; i++)
{
// Add the current item to the temporary ListBox
tempListBox.Items.Add(listBox10.Items[i]);
// Check if we have collected 6 items or if we are at the last item
if ((i + 1) % 6 == 0 || i == listBox10.Items.Count - 1)
{
// Call the print method with the current batch of items
var filledTemplate = printTemplate.FillPrintGridTemplate(tempListBox);
filledTemplates.Add(filledTemplate); // Add the filled template to the list
filledTemplate = null;
//filledTemplates.Add(printTemplate.FillPrintGridTemplate(tempListBox));
//Print_WPF_Preview(printTemplate.FillPrintGridTemplate(tempListBox));
// Clear the temporary ListBox for the next batch
tempListBox.Items.Clear();
tempListBox = new ListBox();
//printTemplate.Close();
}
}
Print_WPF_Preview(filledTemplates);
//printTemplate.Show();
// Close the print template if needed
//printTemplate.Close();
}
I have a listbox with the items included. As on one print page only 6 elements can be displayed, I check when I have 6 elements or I have the last item and pass them to the FillPrintGridTemplate method.
In this window I've created a template grid, where I fill every time the it passes the WPF elements, and return afterwards the grid.
When I only have <=6 items, all works fine, and I get one page with the correct QR codes to be printed out. But as soon at there are more than 6 items, I get 2 or more pages in my XPS document which is correct, but on every page, I get the same QR codes and information.
I figured out, when I pass here:
var filledTemplate = printTemplate.FillPrintGridTemplate(tempListBox);
the scecond time, the first element in my filledTemplates list gets overwritten. I assume that this is because I use the same grid and overwrites it every time.
public Grid FillPrintGridTemplate(ListBox listBox)
{
Grid virtualGrid = new Grid();
Label[] wnrLabels = { lbl_WNR1, lbl_WNR2, lbl_WNR3, lbl_WNR4, lbl_WNR5, lbl_WNR6 };
Label[] UniqueNumberLabels = { lbl_UniqueNumber1, lbl_UniqueNumber2, lbl_UniqueNumber3, lbl_UniqueNumber4, lbl_UniqueNumber5, lbl_UniqueNumber6 };
Label[] MATNRLabels = { lbl_MATNR1, lbl_MATNR2, lbl_MATNR3, lbl_MATNR4, lbl_MATNR5, lbl_MATNR6 };
Image[] QRCodeImage = { qrCodeImage1, qrCodeImage2, qrCodeImage3, qrCodeImage4, qrCodeImage5, qrCodeImage6 };
ResetElements(wnrLabels, UniqueNumberLabels, MATNRLabels, QRCodeImage);
// Iterate over each item in the ListView
int i = 0;
foreach (var obj in listBox.Items)
{
// Cast the item to UniqueNumberItem
UniqueNumberItem item = obj as UniqueNumberItem;
if (item != null)
{
// Now that we've ensured 'item' is a UniqueNumberItem, we can access its properties
wnrLabels[i].Content = item.WNR;
UniqueNumberLabels[i].Content = item.UniqueNumber;
MATNRLabels[i].Content = item.Matnr;
// Generate QR code for the Unique Number
BitmapImage qrCodeImage = GenerateQRCode(item.UniqueNumber);
// Set the Image control's Source to the QR code
QRCodeImage[i].Source = qrCodeImage;
i++; // Move to the next index for the next item
}
}
return MainGrid;
}
I was thinking about if it's possible to create something like a clone of the grid or some temporary grid elements, of course with their child elements. So I won't overwrite the same grid every time, and get my problem solved. Or is there any better way to get this done?
Just to give you an idea, that's what it's looking like. I also get a random blank paper between every time, but I guess that's another problem
public static void Print_WPF_Preview(List<FrameworkElement> wpf_Elements)
{
string sPrintFileName = "print_preview.xps";
if (File.Exists(sPrintFileName))
{
File.Delete(sPrintFileName);
}
// Create XPS document
using (XpsDocument doc = new XpsDocument(sPrintFileName, FileAccess.ReadWrite))
{
XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(doc);
SerializerWriterCollator output_Document = writer.CreateVisualsCollator();
output_Document.BeginBatchWrite();
// Iterate over each FrameworkElement and write it to the document
foreach (var element in wpf_Elements)
{
output_Document.Write(element);
// Add a new page for each element
output_Document.Write(new PageContent());
}
output_Document.EndBatchWrite();
// Open the document for preview
FixedDocumentSequence preview = doc.GetFixedDocumentSequence();
GenerateUniqueNumber_v2.PrintWindow printWindow = new GenerateUniqueNumber_v2.PrintWindow(preview);
printWindow.Show();
}
}
That will work for me
private void PrintButton_Click(object sender, RoutedEventArgs e)
{
InsertToDB();
PrintDialog printDialog = new PrintDialog();
if (printDialog.ShowDialog() == true)
{
currentItemIndex = 0; // Reset the index for a new print job
DrawingVisual visual = new DrawingVisual();
using (DrawingContext dc = visual.RenderOpen())
{
DrawPage(dc);
}
printDialog.PrintVisual(visual, "Print Document");
}
}
private void DrawPage(DrawingContext dc)
{
double x = 50; // Starting X position
double y = 50; // Starting Y position
double rowHeight = 200; // Height of each row (adjusted for QR code and text)
double columnWidth = 220; // Width of each column
int itemsPerPage = 15; // 12 items per page
int totalItems = Items.Count;
for (int i = 0; i < itemsPerPage; i++)
{
if (currentItemIndex >= totalItems)
{
// No more items to print
return;
}
UniqueNumberItem item = Items[currentItemIndex];
// Generate the QR code for the current item's UniqueNumber
BitmapImage qrCodeImage = GenerateQRCode(item.UniqueNumber);
// Calculate the position for the QR code
int row = i / 3; // 3 columns
int col = i % 3; // 0, 1, or 2 for the column index
// Draw the QR code
dc.DrawImage(qrCodeImage, new System.Windows.Rect(x + col * columnWidth, y + row * rowHeight, 100, 100)); // Adjust size and position as needed
// Prepare the text to be drawn
string wnrText = $"WNR: {item.WNR}";
string uniqueNumberText = $"Unique Number: {item.UniqueNumber}";
string matnrText = $"MATNR: {item.Matnr}";
// Calculate the Y position for the text
double textYPosition = y + 110 + row * rowHeight; // Adjust the base Y position for text
// Draw the WNR text
FormattedText wnrFormattedText = new FormattedText(
wnrText,
System.Globalization.CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
new Typeface("Arial"),
12,
System.Windows.Media.Brushes.Black); // Use WPF Brushes
dc.DrawText(wnrFormattedText, new System.Windows.Point(x + col * columnWidth, textYPosition));
// Draw the Unique Number text
FormattedText uniqueNumberFormattedText = new FormattedText(
uniqueNumberText,
System.Globalization.CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
new Typeface("Arial"),
12,
System.Windows.Media.Brushes.Black); // Use WPF Brushes
dc.DrawText(uniqueNumberFormattedText, new System.Windows.Point(x + col * columnWidth, textYPosition + 20)); // Adjust Y position for Unique Number
// Draw the MATNR text
FormattedText matnrFormattedText = new FormattedText(
matnrText,
System.Globalization.CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
new Typeface("Arial"),
12,
System.Windows.Media.Brushes.Black); // Use WPF Brushes
dc.DrawText(matnrFormattedText, new System.Windows.Point(x + col * columnWidth, textYPosition + 40)); // Adjust Y position for MATNR
currentItemIndex++; // Move to the next item
}
// Check if there are more pages
if (currentItemIndex < totalItems)
{
// More items to print, so we need to print another page
DrawingVisual newVisual = new DrawingVisual();
using (DrawingContext newDc = newVisual.RenderOpen())
{
DrawPage(newDc); // Draw the next page
}
// Print the new visual
PrintDialog printDialog = new PrintDialog();
printDialog.PrintVisual(newVisual, "Print Document");
}
}