So I have a program which I want to create as a POS Program for restaurant (practicing). The main problem is I add everything product from my program and fill out the details that I want (Name, Address etc. for delivery purposes). For the first time everything goes pretty well and it prints out a nice looking receipt but after that. The printPage method get called for the amount of times which I used it before like a queue which remembers all of the past printings and at the end it is overlapping.
Here is the code for my Printer class. Which I call from my Form1.cs
//Printer.cs
public class Printer
{
public Printer(List<Stuff> _StuffList, OtherClass _OtherClass)
{
this._StuffList = _StuffList;
this._OtherClass = _OtherClass;
}
public void printPage(object sender, PrintPageEventArgs e)
{
Graphics graphics = e.Graphics;
//The other stuff below is just receipt drawing.
}
And Here is my Form1.cs
//Form1.cs
Printer printer;
private void btn_print_Click(object sender, EventArgs e)
{
OtherClass = new _OtherClass(data_from_textbox here));
printer = new Printer(StuffList, OtherClass);
printReceipt(printer);
StuffList.Clear();
listBox.Items.Clear();
OtherClass.Clear();
//reset TextBox & Labels
label.Text = "";
textBox.Text = "";
}
private static String FILE = Environment.CurrentDirectory + #"\FILE.txt";
private void printReceipt(Printer printer)
{
FileStream fs = new FileStream(FILE, FileMode.Open);
StreamReader sr = new StreamReader(fs);
stringToPrint = sr.ReadToEnd();
//printDocument.PrinterSettings.PrinterName = "EPSON TM-T20III Receipt";
printDocument.PrinterSettings.PrinterName = "Microsoft Print to PDF";
printDocument.PrintPage += new PrintPageEventHandler(printer.printPage);
printDocument.Print();
sr.Close();
fs.Close();
}
I use the NTWAIN library, found a good solution for interacting with this library, modified it a little. This is actually it:
public class ScanningTwain
{
List<Image> ImagesScan;
DataSource myDS;
TwainSession session;
public ScanningTwain()
{
ImagesScan = new List<Image>();
}
public List<Image> Scan(decimal dpi)
{
ImagesScan.Clear();
var appId = TWIdentity.CreateFromAssembly(DataGroups.Image, Assembly.GetExecutingAssembly());
session = new TwainSession(appId);
session.TransferReady += session_TransferReady;
session.DataTransferred += session_DataTransferred;
session.SourceDisabled += session_SourceDisable;
session.Open();
IEnumerable<DataSource> lesSources = session.GetSources();
myDS = lesSources.FirstOrDefault();
myDS.Open();
PixelType typeCouleur = PixelType.Gray;
if (myDS.Capabilities.ICapPixelType.CanSet &&
myDS.Capabilities.ICapPixelType.GetValues().Contains(typeCouleur))
{
myDS.Capabilities.ICapPixelType.SetValue(typeCouleur);
}
TWFix32 DPI = (float)dpi;
if (myDS.Capabilities.ICapXResolution.CanSet &&
myDS.Capabilities.ICapXResolution.GetValues().Contains(DPI))
{
myDS.Capabilities.ICapXResolution.SetValue(DPI);
}
if (myDS.Capabilities.ICapYResolution.CanSet &&
myDS.Capabilities.ICapYResolution.GetValues().Contains(DPI))
{
myDS.Capabilities.ICapYResolution.SetValue(DPI);
}
myDS.Enable(SourceEnableMode.ShowUI, false, System.IntPtr.Zero);
EventWaitHandle session_SourceDisable_Wait = new EventWaitHandle(false, EventResetMode.AutoReset);
session_SourceDisable_Wait.WaitOne();
return ImagesScan;
}
void session_DataTransferred(object sender, NTwain.DataTransferredEventArgs e)
{
if (e.NativeData != IntPtr.Zero)
{
Bitmap img = null;
//Need to save out the data.
Stream s = e.GetNativeImageStream();
BitmapSource bitmapsource = s.ConvertToWpfBitmap();
using (MemoryStream outStream = new MemoryStream())
{
BitmapEncoder enc = new BmpBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(bitmapsource));
enc.Save(outStream);
img = new Bitmap(outStream);
}
if (img != null)
{
ImagesScan.Add(img);
}
}
}
void session_SourceDisable(object sender, EventArgs e)
{
myDS.Close();
session.Close();
}
void session_TransferReady(object sender, NTwain.TransferReadyEventArgs e)
{
}
}
The error occurs at the line: myDS.Open () ; in the public List <Image> Scan (decimal dpi) method writes that myDS = null , I suppose this is due to the fact that when this line is executed session.Open () ; DSM does not appear so that you can select a scanner. Although I downloaded DSM from the official site. Thank you in advance for your help!
I am new to C# and reports. What am I doing wrong or missing?
I have searched and searched and for the life of me can't figure this out.
I am using C# Windows Forms Application. I have report2.rdlc and everything works great in the report viewer, the text boxes and data in the tablix print as expected. When I print directly to the printer without using the report viewer, the text boxes print, but the data in the tablix does not print. Provided below is a screenshot of the Report Data window along with the coding and explanation.
Report Data Image
StatusCodes.cs form: Contains print button that has DialogResult. If "Yes" is clicked, StatusCodePreview.cs form opens. This has the report viewer (no problems here). If "No" is clicked, this triggers PrintWithoutReportViewer.cs and the report is printed directly to the default printer (problem: only text boxes and column headers are printing, data is not).
private void btn_CodePrint_Click(object sender, EventArgs e)
{
var message = "Do you wish to preview the report before printing?";
var title = "Preview Report";
DialogResult dg = MessageBox.Show(message, title, MessageBoxButtons.YesNo);
if (dg == DialogResult.Yes)
{
StatusCodePreview scp = new StatusCodePreview();
scp.Show();
}
else if (dg == DialogResult.No)
{
DataTable dt = new StatusCodesPrintDataSet.DataTable1DataTable();
LocalReport report = new LocalReport {ReportEmbeddedResource = "Toolbar.Report2.rdlc"};
report.DataSources.Add(new ReportDataSource("StatCodePrintDataSet1", dt));
report.PrintToPrinter();
}
}
Code for PrintWithoutReportViewer.cs
public static class PrintWithoutReportViewer
{
private static int m_CurrentPageIndex;
private static IList<Stream> m_Streams;
private static PageSettings m_PageSettings;
public static Stream CreateStream(string name, string fileNameExtension, Encoding encoding, string mimeType, bool willSeek)
{
Stream stream = new MemoryStream();
m_Streams.Add(stream);
return stream;
}
public static void Export(LocalReport report, bool print = true)
{
PaperSize paperSize = m_PageSettings.PaperSize;
Margins margins = m_PageSettings.Margins;
string deviceInfo = string.Format(
CultureInfo.InvariantCulture,
"<DeviceInfo>" +
"<OutputFormat>EMF</OutputFormat>" +
"<PageWidth>{5}</PageWidth>" +
"<PageHeight>{4}</PageHeight>" +
"<MarginTop>{0}</MarginTop>" +
"<MarginLeft>{1}</MarginLeft>" +
"<MarginRight>{2}</MarginRight>" +
"<MarginBottom>{3}</MarginBottom>" +
"</DeviceInfo>",
ToInches(margins.Top),
ToInches(margins.Left),
ToInches(margins.Right),
ToInches(margins.Bottom),
ToInches(paperSize.Height),
ToInches(paperSize.Width));
Warning[] warnings;
m_Streams = new List<Stream>();
report.Render("Image", deviceInfo, CreateStream,
out warnings);
foreach (Stream stream in m_Streams)
stream.Position = 0;
if (print)
{
Print();
//PrintDialog startPrint = new PrintDialog();
//startPrint.ShowDialog();
}
}
public static void PrintPage(object sender, PrintPageEventArgs e)
{
Stream pageToPrint = m_Streams[m_CurrentPageIndex];
pageToPrint.Position = 0;
using (Metafile pageMetaFile = new Metafile(pageToPrint))
{
Rectangle adjustedRect = new Rectangle(
e.PageBounds.Left - (int)e.PageSettings.HardMarginX,
e.PageBounds.Top - (int)e.PageSettings.HardMarginY,
e.PageBounds.Width,
e.PageBounds.Height);
e.Graphics.FillRectangle(Brushes.White, adjustedRect);
e.Graphics.DrawImage(pageMetaFile, adjustedRect);
m_CurrentPageIndex++;
e.HasMorePages = m_CurrentPageIndex < m_Streams.Count;
}
}
public static void Print()
{
if (m_Streams == null || m_Streams.Count == 0)
throw new Exception("Error: no stream to print.");
PrintDocument printDoc = new PrintDocument();
if (!printDoc.PrinterSettings.IsValid)
{
throw new Exception("Error: cannot find the default printer.");
}
else
{
printDoc.PrintPage += new PrintPageEventHandler(PrintPage);
m_CurrentPageIndex = 0;
printDoc.Print();
}
}
public static void PrintToPrinter(this LocalReport report)
{
m_PageSettings = new PageSettings();
ReportPageSettings reportPageSettings = report.GetDefaultPageSettings();
m_PageSettings.PaperSize = reportPageSettings.PaperSize;
m_PageSettings.Margins = reportPageSettings.Margins;
Export(report);
}
public static void DisposePrint()
{
if (m_Streams != null)
{
foreach (Stream stream in m_Streams)
stream.Close();
m_Streams = null;
}
}
private static string ToInches(int hundrethsOfInch)
{
double inches = hundrethsOfInch / 100.0;
return inches.ToString(CultureInfo.InvariantCulture) + "in";
}
}
I was originally trying to print using PrintDialog (I was wanting this option to allow user to still be able to select a printer), but that doesn't work at all and just led me to getting so frustrated. I am now just trying to use Print();
Like I said at the beginning, I am new at this and I'm lost. It would be greatly appreciated if anyone can help me with this.
Im new to the c#, currently Im making a POS application witch can print a Receipt. I used reportviewer component for create the Receipt. I is working. but I couldn't pass the print command directly. When it is preview I have to press Print Button manually. but I need to print it automatically without a preview. here is my beginning of the code. Is there any way to bind this repotviewr with PrintDocument or how can I print this reportviewer automatically
Open FormReceipt
DateTime thisDay = DateTime.Today;
FormReceipt frmReceipt = new FormReceipt(order, String.Format("{0:n}", totalAmmount), String.Format("{0:n}", paidammount), String.Format("{0:n}",change), thisDay.ToString("g"), discount.ToString());
frmReceipt.ShowDialog();
Set Parameters and Binding Source
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Drawing.Printing;
using Microsoft.Reporting.WinForms;
namespace Pos
{
public partial class FormReceipt : MetroFramework.Forms.MetroForm
{
List<Receipt> _list;
string _total, _cash, _change, _date, _user, _discount;
public FormReceipt(List<Receipt> datasource, string total,string cash, string change, string date, string discount)
{
InitializeComponent();
_list = datasource;
_total = total;
_cash = cash;
_change = change;
_date = date;
_user = Sessiondata.user;
_discount = discount;
}
private void FormReceipt_Load(object sender, EventArgs e)
{
ReceiptBindingSource.DataSource = _list;
Microsoft.Reporting.WinForms.ReportParameter[] para = new Microsoft.Reporting.WinForms.ReportParameter[]{
new Microsoft.Reporting.WinForms.ReportParameter("pTotal",_total),
new Microsoft.Reporting.WinForms.ReportParameter("pCash",_cash),
new Microsoft.Reporting.WinForms.ReportParameter("pChange",_change),
new Microsoft.Reporting.WinForms.ReportParameter("pDate",_date),
new Microsoft.Reporting.WinForms.ReportParameter("pUser",_user),
new Microsoft.Reporting.WinForms.ReportParameter("pItems",_list.Count.ToString()),
new Microsoft.Reporting.WinForms.ReportParameter("pDiscount",_discount+"%")
};
this.reportViewer1.LocalReport.SetParameters(para);
this.reportViewer1.RefreshReport();
}
private void reportViewer1_Load(object sender, EventArgs e)
{
}
}
}
I am posting my code which is working fine as you want. Check this code and do the customization in the code as needed.
List<Receipt> _list;
string _total, _cash, _change, _date, _user, _discount;
public FormReceipt(List<Receipt> datasource, string total,string cash, string change, string date, string discount)
{
InitializeComponent();
_list = datasource;
_total = total;
_cash = cash;
_change = change;
_date = date;
_user = Sessiondata.user;
_discount = discount;
}
private void FormReceipt_Load(object sender, EventArgs e)
{
ReceiptBindingSource.DataSource = _list;
Microsoft.Reporting.WinForms.ReportParameter[] para = new Microsoft.Reporting.WinForms.ReportParameter[]{
new Microsoft.Reporting.WinForms.ReportParameter("pTotal",_total),
new Microsoft.Reporting.WinForms.ReportParameter("pCash",_cash),
new Microsoft.Reporting.WinForms.ReportParameter("pChange",_change),
new Microsoft.Reporting.WinForms.ReportParameter("pDate",_date),
new Microsoft.Reporting.WinForms.ReportParameter("pUser",_user),
new Microsoft.Reporting.WinForms.ReportParameter("pItems",_list.Count.ToString()),
new Microsoft.Reporting.WinForms.ReportParameter("pDiscount",_discount+"%")
};
this.reportViewer1.LocalReport.SetParameters(para);
this.reportViewer1.RefreshReport();
Export(ReportViewer1.LocalReport, false);
Print();
Dispose();
}
private int m_currentPageIndex;
private IList<Stream> m_streams;
private Stream CreateStream(string name,
string fileNameExtension, Encoding encoding,
string mimeType, bool willSeek)
{
Stream stream = new MemoryStream();
m_streams.Add(stream);
return stream;
}
private void Export(LocalReport report, bool isLandscape)
{
string deviceInfo = string.Empty;
if (isLandscape)
{
deviceInfo =
#"<DeviceInfo>
<OutputFormat>EMF</OutputFormat>
<PageWidth>11in</PageWidth>
<PageHeight>8.5in</PageHeight>
<MarginTop>0.25in</MarginTop>
<MarginLeft>0.25in</MarginLeft>
<MarginRight>0.25in</MarginRight>
<MarginBottom>0.25in</MarginBottom>
</DeviceInfo>";
}
else
{
deviceInfo =
#"<DeviceInfo>
<OutputFormat>EMF</OutputFormat>
<PageWidth>8.5in</PageWidth>
<PageHeight>11in</PageHeight>
<MarginTop>0.25in</MarginTop>
<MarginLeft>0.25in</MarginLeft>
<MarginRight>0.25in</MarginRight>
<MarginBottom>0.25in</MarginBottom>
</DeviceInfo>";
}
Warning[] warnings;
m_streams = new List<Stream>();
// Create Report DataSource
ReportDataSource rds = new ReportDataSource();
rds.Value = _list;
ReportViewer1.LocalReport.DataSources.Clear();
ReportViewer1.LocalReport.DataSources.Add(rds);
report.Render("Image", deviceInfo, CreateStream,
out warnings);
foreach (Stream stream in m_streams)
stream.Position = 0;
}
private void Print()
{
PrinterSettings settings = new PrinterSettings(); //set printer settings
string printerName = settings.PrinterName; //use default printer name
if (m_streams == null || m_streams.Count == 0)
throw new Exception("Error: no stream to print.");
PrintDocument printDoc = new PrintDocument();
if (!printDoc.PrinterSettings.IsValid)
{
Response.Write("<script>alert('" + printerName + "')</script>");
}
else
{
printDoc.PrintPage += new PrintPageEventHandler(PrintPage);
m_currentPageIndex = 0;
printDoc.Print();
}
}
private void PrintPage(object sender, PrintPageEventArgs ev)
{
Metafile pageImage = new
Metafile(m_streams[m_currentPageIndex]);
ev.Graphics.DrawImage(pageImage, ev.PageBounds);
m_currentPageIndex++;
ev.HasMorePages = (m_currentPageIndex < m_streams.Count);
}
public void Dispose()
{
if (m_streams != null)
{
foreach (Stream stream in m_streams)
stream.Close();
m_streams = null;
}
}
add this code to class and then call function PrintToPrinter and pass reportviewer as parameter then report will print silently
for more details :
https://learn.microsoft.com/en-us/previous-versions/ms252091(v=vs.140)?redirectedfrom=MSDN
private static List<Stream> m_streams;
private static int m_currentPageIndex = 0;
static LocalReport report = new LocalReport();
public static void PrintToPrinter(LocalReport report)
{
Export(report);
}
public static void Export(LocalReport report, bool print = true)
{
string deviceInfo =
#"<DeviceInfo>
<OutputFormat>EMF</OutputFormat>
<PageWidth>{pageSettings.PaperSize.Width * 100}in</PageWidth>
<PageHeight>{pageSettings.PaperSize.Height * 100}in</PageHeight>
<MarginTop>{pageSettings.Margins.Top * 100}in</MarginTop>
<MarginLeft>{pageSettings.Margins.Left * 100}in</MarginLeft>
<MarginRight>{pageSettings.Margins.Right * 100}in</MarginRight>
<MarginBottom>{pageSettings.Margins.Bottom * 100}in</MarginBottom>
</DeviceInfo>";
Warning[] warnings;
m_streams = new List<Stream>();
report.Render("Image", deviceInfo, CreateStream, out warnings);
foreach (Stream stream in m_streams)
stream.Position = 0;
if (print)
{
Print();
}
}
public static void Print()
{
if (m_streams == null || m_streams.Count == 0)
throw new Exception("Error: no stream to print.");
PrintDocument printDoc = new PrintDocument();
if (!printDoc.PrinterSettings.IsValid)
{
throw new Exception("Error: cannot find the default printer.");
}
else
{
printDoc.PrintPage += new PrintPageEventHandler(PrintPage);
m_currentPageIndex = 0;
printDoc.Print();
}
}
public static Stream CreateStream(string name, string fileNameExtension, Encoding encoding, string mimeType, bool willSeek)
{
Stream stream = new MemoryStream();
m_streams.Add(stream);
return stream;
}
public static void PrintPage(object sender, PrintPageEventArgs ev)
{
Metafile pageImage = new
Metafile(m_streams[m_currentPageIndex]);
// Adjust rectangular area with printer margins.
Rectangle adjustedRect = new Rectangle(
ev.PageBounds.Left - (int)ev.PageSettings.HardMarginX,
ev.PageBounds.Top - (int)ev.PageSettings.HardMarginY,
ev.PageBounds.Width,
ev.PageBounds.Height);
// Draw a white background for the report
ev.Graphics.FillRectangle(Brushes.White, adjustedRect);
// Draw the report content
ev.Graphics.DrawImage(pageImage, adjustedRect);
// Prepare for the next page. Make sure we haven't hit the end.
m_currentPageIndex++;
ev.HasMorePages = (m_currentPageIndex < m_streams.Count);
}
public static void DisposePrint()
{
if (m_streams != null)
{
foreach (Stream stream in m_streams)
stream.Close();
m_streams = null;
}
}
Help to understand the essence of transfer data to another class.
So,Silverlight application.I have page Home.xaml(and its code-behind Home.xaml.cs).There is the button. when I click on the button the following code is executed:
Home.xaml.cs
private void Button_Click_1(object sender, RoutedEventArgs e)
{
OpenFileDialog opendialog = new OpenFileDialog();
opendialog.Multiselect = true;
bool? dialogResult = opendialog.ShowDialog();
if (dialogResult.HasValue && dialogResult.Value)
{
Stream fileStream = opendialog.File.OpenRead();
StreamReader reader = new StreamReader(fileStream);
............
here i need in such data as reader ,because i want this data stream(reader) to send to some completely another classes (for example, one DataProccess.cs):
DataProccess.cs:
namespace SilverlightApplication1.Models
{
public static class DataProcess
{
{
}
}
that will process the data stream (reader from Home.xaml.cs) using regular expressions and output data will place into collection List<>.
how to implement it. I would be happy for a few lines of code from you? :)
Revised code:
Home.xaml.cs:
private void Button_Click(object sender, EventArgs e)
{
OpenFileDialog opendialog = new OpenFileDialog();
opendialog.Multiselect = true;
bool? dialogResult = opendialog.ShowDialog();
if (dialogResult.HasValue && dialogResult.Value)
{
Stream fileStream = opendialog.File.OpenRead();
var processor = new Processor();
ICollection<object> results = processor.Process(fileStream);
}
}
Processor.cs
public class Processor
{
public ICollection<object> Process(Stream stream)
{
StreamReader reader = new StreamReader(stream);
string pattern = #"set vrouter ""([\w-]+)""";
while (!reader.EndOfStream)
{
var matches =
Regex.Matches(reader.ReadToEnd(), pattern)
.Cast<Match>().Where(m => m.Success)
.Select(m => m.Groups[1].Value)
.Distinct();
foreach (var match in matches)
{
var val = match + Environment.NewLine;
return new Collection<object>().Add(val);; //here error
}
}
//return new Collection<object>(val);
}
}
such error:
Error1/Cannot implicitly convert type 'void' to 'System.Collections.Generic.ICollection'
Create a new class that will process your results
public class Processor
{
public ICollection<object> Process(Stream stream)
{
StreamReader reader = new StreamReader(stream);
// do stuff
return new Collection<object>();
}
}
Then create an instance of it and call the Process method
Stream fileStream = opendialog.File.OpenRead();
var processor = new Processor();
ICollection<object> results = processor.Process(fileStream);