admin管理员组

文章数量:1187999

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();
    }
}

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();
    }
}
Share Improve this question edited Jan 25 at 13:48 EldHasp 7,9082 gold badges10 silver badges31 bronze badges asked Jan 25 at 9:56 user25434284user25434284 174 bronze badges 1
  • The problem is the "second time". After creating the "first" temporary ListBox (in your loop); which constitutes a "logical page"; you should have just kept going and created a "List" of ListBoxes (i.e. pages) to print out. More "natural". You can add some "tramp" data to the ListBox .Tag property; e.g. "page #". – Gerry Schmitz Commented Jan 25 at 15:30
Add a comment  | 

1 Answer 1

Reset to default 0

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");
         }
     }

本文标签: cCreate a virtual copy of Grid Element and add to XPS documentStack Overflow