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
1 Answer
Reset to default 0That 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
版权声明:本文标题:c# - Create a virtual copy of Grid Element and add to XPS document - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1738366981a2081796.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论