How to set number of copies from textbox to print To ptinter - c#

I'm using this code for printing to printer to print reportviewer without showing dialoge,
but I can't set the number of copies to print
I need a textbox or numericUpDown or anything to put the number of copies
using System;
using System.IO;
using System.Text;
using System.Globalization;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Printing;
using Microsoft.Reporting.WinForms;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace NewLabelPrinter
{
/// <summary>
/// The ReportPrintDocument will print all of the pages of a ServerReport or LocalReport.
/// The pages are rendered when the print document is constructed. Once constructed,
/// call Print() on this class to begin printing.
/// </summary>
class AutoPrintCls : PrintDocument
{
private PageSettings m_pageSettings;
private int m_currentPage;
private List<Stream> m_pages = new List<Stream>();
public AutoPrintCls(ServerReport serverReport)
: this((Report)serverReport)
{
RenderAllServerReportPages(serverReport);
}
public AutoPrintCls(LocalReport localReport)
: this((Report)localReport)
{
RenderAllLocalReportPages(localReport);
}
private AutoPrintCls(Report report)
{
// Set the page settings to the default defined in the report
ReportPageSettings reportPageSettings = report.GetDefaultPageSettings();
// The page settings object will use the default printer unless
// PageSettings.PrinterSettings is changed. This assumes there
// is a default printer.
m_pageSettings = new PageSettings();
m_pageSettings.PaperSize = reportPageSettings.PaperSize;
m_pageSettings.Margins = reportPageSettings.Margins;
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
foreach (Stream s in m_pages)
{
s.Dispose();
}
m_pages.Clear();
}
}
protected override void OnBeginPrint(PrintEventArgs e)
{
base.OnBeginPrint(e);
m_currentPage = 0;
}
protected override void OnPrintPage(PrintPageEventArgs e)
{
base.OnPrintPage(e);
Stream pageToPrint = m_pages[m_currentPage];
pageToPrint.Position = 0;
// Load each page into a Metafile to draw it.
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);
// Draw a white background for the report
e.Graphics.FillRectangle(Brushes.White, adjustedRect);
// Draw the report content
e.Graphics.DrawImage(pageMetaFile, adjustedRect);
// Prepare for next page. Make sure we haven't hit the end.
m_currentPage++;
e.HasMorePages = m_currentPage < m_pages.Count;
}
}
protected override void OnQueryPageSettings(QueryPageSettingsEventArgs e)
{
e.PageSettings = (PageSettings)m_pageSettings.Clone();
}
private void RenderAllServerReportPages(ServerReport serverReport)
{
try
{
string deviceInfo = CreateEMFDeviceInfo();
// Generating Image renderer pages one at a time can be expensive. In order
// to generate page 2, the server would need to recalculate page 1 and throw it
// away. Using PersistStreams causes the server to generate all the pages in
// the background but return as soon as page 1 is complete.
NameValueCollection firstPageParameters = new NameValueCollection();
firstPageParameters.Add("rs:PersistStreams", "True");
// GetNextStream returns the next page in the sequence from the background process
// started by PersistStreams.
NameValueCollection nonFirstPageParameters = new NameValueCollection();
nonFirstPageParameters.Add("rs:GetNextStream", "True");
string mimeType;
string fileExtension;
Stream pageStream = serverReport.Render("IMAGE", deviceInfo, firstPageParameters, out mimeType, out fileExtension);
// The server returns an empty stream when moving beyond the last page.
while (pageStream.Length > 0)
{
m_pages.Add(pageStream);
pageStream = serverReport.Render("IMAGE", deviceInfo, nonFirstPageParameters, out mimeType, out fileExtension);
}
}
catch (Exception e)
{
MessageBox.Show("possible missing information :: " + e);
}
}
private void RenderAllLocalReportPages(LocalReport localReport)
{
try
{
string deviceInfo = CreateEMFDeviceInfo();
Warning[] warnings;
localReport.Render("IMAGE", deviceInfo, LocalReportCreateStreamCallback, out warnings);
}
catch (Exception e)
{
MessageBox.Show("error :: " + e);
}
}
private Stream LocalReportCreateStreamCallback(
string name,
string extension,
Encoding encoding,
string mimeType,
bool willSeek)
{
MemoryStream stream = new MemoryStream();
m_pages.Add(stream);
return stream;
}
private string CreateEMFDeviceInfo()
{
PaperSize paperSize = m_pageSettings.PaperSize;
Margins margins = m_pageSettings.Margins;
// The device info string defines the page range to print as well as the size of the page.
// A start and end page of 0 means generate all pages.
return string.Format(
CultureInfo.InvariantCulture,
"<DeviceInfo><OutputFormat>emf</OutputFormat><StartPage>0</StartPage><EndPage>0</EndPage><MarginTop>{0}</MarginTop><MarginLeft>{1}</MarginLeft><MarginRight>{2}</MarginRight><MarginBottom>{3}</MarginBottom><PageHeight>{4}</PageHeight><PageWidth>{5}</PageWidth></DeviceInfo>",
ToInches(margins.Top),
ToInches(margins.Left),
ToInches(margins.Right),
ToInches(margins.Bottom),
ToInches(paperSize.Height),
ToInches(paperSize.Width));
}
private static string ToInches(int hundrethsOfInch)
{
double inches = hundrethsOfInch / 100.0;
return inches.ToString(CultureInfo.InvariantCulture) + "in";
}
}
}
this is the Print button
private void btnPrint_Click_1(object sender, EventArgs e)
{
AutoPrintCls autoprintme = new AutoPrintCls(reportViewer1.LocalReport);
autoprintme.Print();
}

Your btnPrint_Click_1 event can refer to the following code:
private void btnPrint_Click_1(object sender, EventArgs e)
{
AutoPrintCls autoprintme = new AutoPrintCls(reportViewer1.LocalReport);
autoprintme.PrinterSettings.Copies = Convert.ToInt16(numericUpDown1.Value);
autoprintme.Print();
}

Related

Sorting excel sheets c# || how to exclude lines that are missing a specific cell

I am currently working on a windows forms app using c# that will be able to convert Pastel Partner trial balances to Pastel Evolution compatible balances.
I am trying to implement code that will skip all lines in the sheet that do not have account codes (col 2)
Please assist with a code example on how to do this, it would be highly appreciated!
The excel sheet needs to convert from this (Partner)...
To this (Evolution)...
This is my form and code so far...
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;
namespace Evo_Mod
{
public partial class Form1 : Form
{
public string date; // set by user
public string codeDate; // set by date and OB string
public string OB = "OB"; // set value
public string zero = "0"; // set value
public string accCode; // needs to be read from the first excell sheet and printed with a ">"
public string contraCode = "9990>001"; // set value
public bool credCheck = false; // bool that is interactive
public bool debCheck = false; // bool that is interactive depending on whether the account is in credit or debit
public string fileName = ""; // set from the openFileDialog
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e) // lets user select csv file.
{
openFileDialog1.ShowDialog();
openFileDialog1.Filter = "CSV Files (L*.csv)|L*.csv"; // Filters to only .csv files
fileName = openFileDialog1.FileName;
if(openFileDialog1.ShowDialog() == DialogResult.OK)
{
lblFileName.Text = openFileDialog1.FileName; // prints file directory
}
}
public static string[] ReadCSV(string searchTerm , string filePath , int positionOfSearch)
{
positionOfSearch--; // moves over by 1 (more understandable)
string[] recordNotFound = { " Record Not Found " }; // array for errors
try
{
string[] lines = System.IO.File.ReadAllLines(#filePath);
for (int i = 0; i < lines.Length; i++)
{
string[] fields = lines[i].Split(',');
if (recordMatches(searchTerm , fields , positionOfSearch))
{
return fields;
}
}
return recordNotFound;
}
catch(Exception ex)
{
Console.WriteLine("error");
return recordNotFound;
throw new ApplicationException("Error : ", ex);
}
}
public static bool recordMatches(string searchTerm , string[] record , int positionOfSearch)
{
if (record[positionOfSearch] != " ")
{
return true;
}
return false;
}
private void btnConvert_Click(object sender, EventArgs e)
{
DateTime tempDate = dateTimePicker1.Value;
codeDate = "OB " + tempDate.ToString("dd/MM/yyyy");
date = tempDate.ToString("dd/MM/yyyy");
}
}
}
If the account codes are in col 2, then you can check for empty values in the loop which you already have
string[] fields = lines[i].Split(',');
if (fields[1] != "") <-- check if account code is an empty string
{
if (recordMatches(searchTerm , fields , positionOfSearch))
{
...

Adding Page Numbers

I haven't really written anything outside of Powershell in a long time, and I know this is ugly, but I can't seem to figure out why my new PDF is not adding the page numbers. I pulled the example from this itext kb.
I tried to make this basic app so people in the office could add the page numbers to PDF's. Here's what I have so far. It will create the new PDF (duplicate of the original), but it's not adding the page numbers.
Basically they use button1 to find their PDF via the Windows File Explorer dialog. It just stores the filename in a textbox. The second button is the "save" and should take the src file and make a copy of the src with only adding the page number at the bottom of the file (or anywhere at this point).
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using iText.Kernel.Pdf;
using iText.Layout;
using iText.Layout.Element;
using iText.Layout.Properties;
namespace PDFManipulation
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
int size = -1;
DialogResult result = openFileDialog1.ShowDialog(); // Show the dialog.
if (result == DialogResult.OK) // Test result.
{
string file = openFileDialog1.FileName;
try
{
string text = File.ReadAllText(file);
size = text.Length;
textBox1.Text = file;
}
catch (System.IO.IOException)
{
}
}
Console.WriteLine(size); // <-- Shows file size in debugging mode.
Console.WriteLine(result); // <-- For debugging use.
}
private void button2_Click(object sender, EventArgs e)
{
Stream myStream;
//SaveFileDialog saveFileDialog1 = new SaveFileDialog();
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
if ((myStream = saveFileDialog1.OpenFile()) != null)
{
// Code to write the stream goes here.
myStream.Close();
string SRC = textBox1.Text;
string DEST = saveFileDialog1.FileName;
FileInfo file = new FileInfo(DEST);
file.Directory.Create();
PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(DEST));
Document doc = new Document(pdfDoc);
int numberOfPages = pdfDoc.GetNumberOfPages();
for (int i = 1; i <= numberOfPages; i++)
{
// Write aligned text to the specified by parameters point
doc.ShowTextAligned(new Paragraph("page " + i + " of " + numberOfPages),559, 806, i, TextAlignment.CENTER, VerticalAlignment.TOP, 0);
}
doc.Close();
}
}
MessageBox.Show("PDF Page Numbering Added!", "Pages Added",MessageBoxButtons.OK);
Application.Exit();
}
}
}
I'm a dumb dumb. The x,y coordinates were off as the value 812 for the height is off the page.

C# RDLC Report Printing [duplicate]

I have an application where I have to print a RDLC report without showing the printDialog and using the default specified printer defined in the application. Below is my test implementaion code.
Microsoft.Reporting.WinForms.ReportViewer reportViewerSales = new Microsoft.Reporting.WinForms.ReportViewer();
Microsoft.Reporting.WinForms.ReportDataSource reportDataSourceSales = new Microsoft.Reporting.WinForms.ReportDataSource();
reportViewerSales.Reset();
reportViewerSales.LocalReport.ReportPath = #"Sales.rdlc";
reportDataSourceSales.Name = "SalesTableDataSet";
int i = 1;
foreach (Product item in ProductSalesList)
{
dataset.CurrentSales.AddCurrentSalesRow(i, item.Name, item.Quantity.ToString(), item.Price.ToString(), item.Price.ToString());
i++;
}
reportDataSourceSales.Value = dataset.CurrentSales;
reportViewerSales.LocalReport.DataSources.Add(reportDataSourceSales);
dataset.EndInit();
reportViewerSales.RefreshReport();
reportViewerSales.RenderingComplete += new RenderingCompleteEventHandler(PrintSales);
And here is my Rendering Complete Method
public void PrintSales(object sender, RenderingCompleteEventArgs e)
{
try
{
reportViewerSales.PrintDialog();
reportViewerSales.Clear();
reportViewerSales.LocalReport.ReleaseSandboxAppDomain();
}
catch (Exception ex)
{
}
}
I just gave a quick look to a class I created to print directly and I think I took some ideas from this walkthrough:
Printing a Local Report without Preview
i have made an extension class to #tezzos answer. which might make it more easier.
use this Gist Here to get the extension class i wrote. include it to your project. don't for get namespace :D
LocalReport report = new LocalReport();
report.ReportEmbeddedResource = "Your.Reports.Path.rdlc";
report.DataSources.Add(new ReportDataSource("DataSet1", getYourDatasource()));
report.PrintToPrinter();
PrintToPrinter Method will be available on LocalReport. Might Help someone
Download C# full Project file
using Microsoft.Reporting.WinForms;
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;
namespace WindowsFormsApp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.UiLabelUpTableAdapter.Fill(this.POSDataSet.UiLabelUp);
this.reportViewer1.RefreshReport();
}
private void buttonPrintReport_Click(object sender, EventArgs e)
{
ReportViewer InvoiceReport = new ReportViewer();
InvoiceReport.LocalReport.ReportPath = #"C:\Users\Chamod\source\repos\WindowsFormsApp\WindowsFormsApp\Report1.rdlc";
ReportDataSource DataSet1 = new ReportDataSource("DataSet1", UiLabelUpBindingSource);
InvoiceReport.LocalReport.DataSources.Add(DataSet1);
LocalReport lr = InvoiceReport.LocalReport;
lr.PrintToPrinter();
InvoiceReport.Clear();
}
}
}
using Microsoft.Reporting.WinForms;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Printing;
using System.IO;
namespace WindowsFormsApp
{
public static class LocalReportExtensions
{
public static void PrintToPrinter(this LocalReport report)
{
PageSettings pageSettings = new PageSettings();
pageSettings.PaperSize = report.GetDefaultPageSettings().PaperSize;
pageSettings.Landscape = report.GetDefaultPageSettings().IsLandscape;
pageSettings.Margins = report.GetDefaultPageSettings().Margins;
Print(report, pageSettings);
}
public static void Print(this LocalReport report, PageSettings pageSettings)
{
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;
var streams = new List<Stream>();
var pageIndex = 0;
report.Render("Image", deviceInfo,
(name, fileNameExtension, encoding, mimeType, willSeek) =>
{
MemoryStream stream = new MemoryStream();
streams.Add(stream);
return stream;
}, out warnings);
foreach (Stream stream in streams)
stream.Position = 0;
if (streams == null || streams.Count == 0)
throw new Exception("No stream to print.");
using (PrintDocument printDocument = new PrintDocument())
{
printDocument.DefaultPageSettings = pageSettings;
if (!printDocument.PrinterSettings.IsValid)
throw new Exception("Can't find the default printer.");
else
{
printDocument.PrintPage += (sender, e) =>
{
Metafile pageImage = new Metafile(streams[pageIndex]);
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(pageImage, adjustedRect);
pageIndex++;
e.HasMorePages = (pageIndex < streams.Count);
e.Graphics.DrawRectangle(Pens.Red, adjustedRect);
};
printDocument.EndPrint += (Sender, e) =>
{
if (streams != null)
{
foreach (Stream stream in streams)
stream.Close();
streams = null;
}
};
printDocument.Print();
}
}
}
}
}
public void PrintSales(object sender, RenderingCompleteEventArgs e)
{
try
{
reportViewerSales.PageSetupDailog();
reportViewerSales.PrintDialog();
reportViewerSales.Clear();
reportViewerSales.LocalReport.ReleaseSandboxAppDomain();
}
catch (Exception ex)
{
}
}

How can I get client PC Printer settings using C#, asp.net

I have SSRS report runnig on a web application. I want to print SSRS report data directly on the client's printer. The application works well in my pc but when I publish the application on IIS web server, instead of retrieving the printer settings of client pc, the application is trying to look for printers that are installed in the server machine.
I am using System.Drawing.Printing, Is there any way to get the settings of installed printer in the client computer or can we print SSRS reports from Web using C# ?
I am using following code.
using System;
using System.IO;
using System.Text;
using System.Globalization;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Printing;
using System.Collections.Specialized;
using System.Collections.Generic;
using Microsoft.Reporting.WebForms;
using SeaWorld.Common.Helper;
namespace SeaWorld.BusinessObjects.BAL.Generated
{
public class ReportPrintDocument : PrintDocument
{
private PageSettings m_pageSettings;
private int m_currentPage;
private List<Stream> m_pages = new List<Stream>();
public ReportPrintDocument(ServerReport serverReport): this((Report)serverReport)
{
RenderAllServerReportPages(serverReport);
}
//public ReportPrintDocument(LocalReport localReport): this((Report)localReport)
//{
// RenderAllLocalReportPages(localReport);
//}
private ReportPrintDocument(Report report)
{
// Set the page settings to the default defined in the report
ReportPageSettings reportPageSettings = report.GetDefaultPageSettings();
// The page settings object will use the default printer unless
// PageSettings.PrinterSettings is changed. This assumes there
// is a default printer.
m_pageSettings = new PageSettings();
m_pageSettings.PaperSize = reportPageSettings.PaperSize;
m_pageSettings.Margins = reportPageSettings.Margins;
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing)
{
foreach (Stream s in m_pages)
{
s.Dispose();
}
m_pages.Clear();
}
}
protected override void OnBeginPrint(PrintEventArgs e)
{
base.OnBeginPrint(e);
m_currentPage = 0;
}
protected override void OnPrintPage(PrintPageEventArgs e)
{
base.OnPrintPage(e);
Stream pageToPrint = m_pages[m_currentPage];
pageToPrint.Position = 0;
// Load each page into a Metafile to draw it.
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);
// Draw a white background for the report
e.Graphics.FillRectangle(Brushes.White, adjustedRect);
// Draw the report content
e.Graphics.DrawImage(pageMetaFile, adjustedRect);
// Prepare for next page. Make sure we haven't hit the end.
m_currentPage++;
e.HasMorePages = m_currentPage < m_pages.Count;
}
}
protected override void OnQueryPageSettings(QueryPageSettingsEventArgs e)
{
e.PageSettings = (PageSettings)m_pageSettings.Clone();
}
private void RenderAllServerReportPages(ServerReport serverReport)
{
string deviceInfo = CreateEMFDeviceInfo();
// Generating Image renderer pages one at a time can be expensive. In order
// to generate page 2, the server would need to recalculate page 1 and throw it
// away. Using PersistStreams causes the server to generate all the pages in
// the background but return as soon as page 1 is complete.
NameValueCollection firstPageParameters = new NameValueCollection();
firstPageParameters.Add("rs:PersistStreams", "True");
// GetNextStream returns the next page in the sequence from the background process
// started by PersistStreams.
NameValueCollection nonFirstPageParameters = new NameValueCollection();
nonFirstPageParameters.Add("rs:GetNextStream", "True");
string mimeType;
string fileExtension;
Stream pageStream = serverReport.Render("IMAGE", deviceInfo, firstPageParameters, out mimeType, out fileExtension);
// The server returns an empty stream when moving beyond the last page.
while (pageStream.Length > 0)
{
m_pages.Add(pageStream);
pageStream = serverReport.Render("IMAGE", deviceInfo, nonFirstPageParameters, out mimeType, out fileExtension);
}
}
private void RenderAllLocalReportPages(LocalReport localReport)
{
string deviceInfo = CreateEMFDeviceInfo();
Warning[] warnings;
localReport.Render("IMAGE", deviceInfo, LocalReportCreateStreamCallback, out warnings);
}
private Stream LocalReportCreateStreamCallback(
string name,
string extension,
Encoding encoding,
string mimeType,
bool willSeek)
{
MemoryStream stream = new MemoryStream();
m_pages.Add(stream);
return stream;
}
private string CreateEMFDeviceInfo()
{
PaperSize paperSize = m_pageSettings.PaperSize;
Margins margins = m_pageSettings.Margins;
// The device info string defines the page range to print as well as the size of the page.
// A start and end page of 0 means generate all pages.
return string.Format(
CultureInfo.InvariantCulture,
"<DeviceInfo><OutputFormat>emf</OutputFormat><StartPage>0</StartPage><EndPage>0</EndPage><MarginTop>{0}</MarginTop><MarginLeft>{1}</MarginLeft><MarginRight>{2}</MarginRight><MarginBottom>{3}</MarginBottom><PageHeight>{4}</PageHeight><PageWidth>{5}</PageWidth></DeviceInfo>",
ToInches(margins.Top),
ToInches(margins.Left),
ToInches(margins.Right),
ToInches(margins.Bottom),
ToInches(paperSize.Height),
ToInches(paperSize.Width));
}
private static string ToInches(int hundrethsOfInch)
{
double inches = hundrethsOfInch / 100.0;
return inches.ToString(CultureInfo.InvariantCulture) + "in";
}
}
}
On print button click
void ctrlSettingToolbar_btnPrintPressed(object sender, EventArgs e)
{
try
{
ReportPrintDocument rp = new ReportPrintDocument(rptBillOfLoadings.ServerReport);
rp.Print();
}
catch (Exception ex)
{
LogHelper.PrintError("Error:", ex);
}
}
You can use javascript function window.Print()
This will list you client machine printers and print your page.
Hope below code will help..try
<html>
<head>
<script>
function page()
{
window.print()
}
</script>
</head>
<body>
<input type="button" value="Print page" onclick="page()">
</body>
</html>
But this will print the whole page..in your case its a report to print
hope this link can guide you
print crystal report to client printer
print report to client default printer

While loop not breaking from signal given by the user in WPF (C#)

I have a WPF which executes a GUI for serial communication. I want to keep triggering the device and recoed the values till the user says stop. I have a global bool variable STOP which I set to false when user presses the stop which in turn should terminate the while loop which triggers the device continuously but the problem is that once the user selects the run button whcih runs the while loop, the WPF app freezes and doesn't accept the STOP button click.
Can someone give me an idea of what is happening here or a any suggestion on how to implement it differently.
Here is my code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO.Ports;
using Keyence.data_class;
using Microsoft.Win32;
using System.IO;
using Keyence;
using System.Threading;
namespace Keyence
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public static string filePath;
public static string fileName;
public static int baudrate = 9600;
public static string thresHold = "60";
public bool STOP = true;
public static char[] buffer = new char[256];
public static string x, y, match;
public static string value;
public static SerialPort port = new SerialPort("COM4", baudrate, Parity.None, 8, StopBits.One);
public MainWindow()
{
InitializeComponent();
//port.DataReceived
//SerialPort port = new SerialPort(COM, baudrate, Parity.None, 8, StopBits.One);
port.Open();
port.NewLine = "\r";
//*******display camera types*****
string[] cameraTypes = new string[] { "CVseries100 ", "CVseries500" , "CVseries700" };
foreach (string cam in cameraTypes)
{
camera_type.Items.Add(cam);
}
//*******select your trigger mode( default is set to NONE)*******
string[] triggerModes = new string[] { "triggerModeNone", "triggerModeDATA", "triggerModeRepeat" };
foreach(string trigger in triggerModes)
{
trigger_mode.Items.Add(trigger);
}
//*****put a default value for thresHold********
threshold_value.Text = thresHold;
//*******add values to the baudrate dropdown********
baud_rate.Items.Add("9600");
baud_rate.Items.Add("19200");
baud_rate.Items.Add("38400");
port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
}
public static void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
value = sp.ReadTo("\r");
string[] values = value.Split(new char[] { ',' });
x = values[0];
y = values[1];
match = values[2];
}
//public static void get_data()
//{
// port.Write("T");
//}
#region encapsulates all the individuals functions when the user changes settings ( UI interaction functions)
private void get_sample_Click(object sender, RoutedEventArgs e)
{
//write code to read x,y,threshold values in the text boxes
port.Write("T");
//MainWindow.get_data();
x_value.Text = string.Format("{0}", x);
y_value.Text = string.Format("{0}", y);
thresholdvalue.Text = string.Format("{0}", match);
}
#region the method opens a savefileDialog(dataFile) and lets user save the file in which data is stored
public void data_file_Click(object sender, RoutedEventArgs e)
{
SaveFileDialog dataFile = new SaveFileDialog();
dataFile.DefaultExt = ".txt";
dataFile.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
dataFile.RestoreDirectory = true;
dataFile.Title = "select or create a new file";
DateTime currentTime = DateTime.Now;
dataFile.Filter = " Text Document |*.txt | Excel |*.xls";
string datepatt = #"M-d-yy_hh-mm_Data";
string saveDT = currentTime.ToString(datepatt);
dataFile.FileName = saveDT;
Nullable<bool> result = dataFile.ShowDialog();
if (result == true)
{
filePath = dataFile.FileName;
fileName = dataFile.SafeFileName;
}
System.IO.FileStream fs = (System.IO.FileStream)dataFile.OpenFile();
using (StreamWriter Write = new StreamWriter(fs))
{
Write.WriteLine("Wafer Placement Data\n\n");
Write.WriteLine("File Name : {0}\n", fileName);
Write.WriteLine("Port Name : COM4\n");
Write.WriteLine("Threshold : {0}\n", threshold_value.Text);
Write.WriteLine("Date : {0}\n\n", Convert.ToString(DateTime.Now));
//************Print Header to the file******************
Write.WriteLine("\tX\tY\tcorrelation\tDate\n");
}
}
#endregion
#region function called when the threshold value is changed
private void threshold_value_TextChanged(object sender, TextChangedEventArgs e)
{
thresHold = threshold_value.Text;
}
#endregion
#region function to write individual data points on the window for checking
private void writeSample(double X, double Y, double threshold)
{
FileStream file = new FileStream(filePath, FileMode.Append, FileAccess.ReadWrite);
using (StreamWriter Writer = new StreamWriter(file))
{
Writer.WriteLine(DateTime.Now);
Writer.WriteLine("\t X \t Y\t threshold% ");
}
}
#endregion
private void run_button_Click(object sender, RoutedEventArgs e)
{
do
{
port.Write("T");
FileStream file = new FileStream(filePath, FileMode.Append, FileAccess.Write);
Thread.Sleep(500);
using (StreamWriter Writer = new StreamWriter(file))
{
Writer.WriteLine("\t{0}\t{1}\t{2}\t{3}", x, y, match, Convert.ToString(DateTime.Now));
}
port.DiscardInBuffer();
} while (STOP);
}
private void stop_button_Click(object sender, RoutedEventArgs e)
{
STOP = false;
}
private void command_TextChanged(object sender, TextChangedEventArgs e)
{
string C = command.Text;
port.WriteLine(C);
}
#endregion
}
}
You need to run your serial port code in separate thread. In your implementation GUI thread is busy w/ serial port communication that is why your window is frozen. The following article explains exactly what you need:
http://www.ryanvice.net/wpf-3-5/using-backgroundworker-with-wpf/

Categories

Resources