I am building winforms .net Application , I have a E-Pos printer on Network ,
using this Code below :
On Form Loading Printer initializing :
explorer = new PosExplorer(this);
DeviceInfo receiptPrinterDevice = explorer.GetDevice("PosPrinter", Properties.Settings.Default.KitchenPrinter); //May need to change this if you don't use a logicial name or use a different one.
kitchenPrinter = (PosPrinter)explorer.CreateInstance(receiptPrinterDevice);
ConnectToPrinter();
private void ConnectToPrinter()
{
kitchenPrinter.Open();
kitchenPrinter.Claim(10000);
kitchenPrinter.DeviceEnabled = true;
}
Function Call on Print Button :
private void PrintReceipt()
{
try
{ kitchenPrinter.PrintNormal(PrinterStation.Receipt, "test");
}
finally
{
}
}
When I want to Switch to Other Form I call Disconnect Function
DisconnectFromPrinter(kitchenPrinter);
Reporting frm = new Reporting(curuser);
frm.Show();
this.Hide();
private void DisconnectFromPrinter(PosPrinter kitchenPrinter)
{
try
{
kitchenPrinter.Release();
kitchenPrinter.Close();
}
catch { }
}
It prints successful one time ,when pressing to print next time it throws and exception
Method ClaimDevice threw an exception. Attempt was made to perform an illegal or unsupported operation with the device, or an invalid parameter value was used.
any suggestion ?
Since the Release command is not being effective and may Claim command is throwing an error every time I am loading my form because it is being Claimed before.
So I have Create a separate Class Called "createPOS"
class createPOS
{
public static PosExplorer explorer;
public static PosPrinter kitchenPrinter;
public static void createPos()
{
explorer = new PosExplorer();
DeviceInfo receiptPrinterDevice = explorer.GetDevice("PosPrinter", Properties.Settings.Default.KitchenPrinter); //May need to change this if you don't use a logicial name or use a different one.
kitchenPrinter = (PosPrinter)explorer.CreateInstance(receiptPrinterDevice);
kitchenPrinter.Open();
kitchenPrinter.Claim(10000);
kitchenPrinter.DeviceEnabled = true;
}
public static void Print(string text){
if (kitchenPrinter.Claimed)
PrintTextLine(kitchenPrinter, text); // kitchenPrinter.PrintNormal(PrinterStation.Receipt, text ); //Print text, then a new line character.
}
private static void PrintTextLine(PosPrinter printer, string text)
{
if (text.Length < printer.RecLineChars)
printer.PrintNormal(PrinterStation.Receipt, text + Environment.NewLine); //Print text, then a new line character.
else if (text.Length > printer.RecLineChars)
printer.PrintNormal(PrinterStation.Receipt, TruncateAt(text, printer.RecLineChars)); //Print exactly as many characters as the printer allows, truncating the rest, no new line character (printer will probably auto-feed for us)
else if (text.Length == printer.RecLineChars)
printer.PrintNormal(PrinterStation.Receipt, text + Environment.NewLine); //Print text, no new line character, printer will probably auto-feed for us.
}
private static string TruncateAt(string text, int maxWidth)
{
string retVal = text;
if (text.Length > maxWidth)
retVal = text.Substring(0, maxWidth);
return retVal;
}
}
and On the Login form that it will only be accessed once I have initialized my printer
createPOS.createPos();
and on MainForm I have called the Printing Method :
createPOS.Print("This allows me to Print Several times");
on that way I am able to print several times and even I navigate to other forms and come back that works fine.
Thank you guys.
Related
This question already has answers here:
Input string was not in a correct format in double.Parse
(5 answers)
Closed 4 years ago.
I'm trying to figure out why when I run my program and press the submit button I get an error saying that my list is in the wrong format. A little background on the program: It's for my visual programming class. The program is for a bank account. I tried to comment on what each section is to make it kinda easier to read
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//Tab 1 Create and close account
private void Submitbtn_Click(object sender, EventArgs e)
{
double x;
if (OpenRdo.Checked == true && Nametxtbx.TextLength > 0)
{
double.TryParse(Nametxtbx.Text, out x);
// after clicking the button there is
// no number; it says system.random
Random acct = new Random();
int AccountNumber = acct.Next(5, 1000);
outputlbl.Text = acct.ToString();
}
// list for accounts
// This is where it says I have the error
// that my list is in the wrong format
var accounts = new List<Account>
{
new Account(Nametxtbx.Text, double.Parse(outputlbl.Text), 0)
};
// Write these records to a file
WriteFile(accounts);
// message box when you create account
if (ValidateChildren(ValidationConstraints.Enabled))
{
MessageBox.Show("Account Created", "Message",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
//writing to the file
static void WriteFile(List<Account> accts)
{
StreamWriter outputFile = File.CreateText("accounts.txt");
string record;
foreach (var acct in accts)
{
record = $"{acct.Name},{acct.Balance}";
Console.WriteLine($"Writing record: {record}");
outputFile.WriteLine(record);
}
outputFile.Close();
}
}
As far as I can tell (this is rather a lot of code), the issues are those lines:
Random acct = new Random();
int AccountNumber = acct.Next(5, 1000);
outputlbl.Text = acct.ToString();
You set the label to "System.Random" (because you call ToString() on the wrong thing). And that can not be sensibly casted into a integer later.
Ideally you should not even retrieve the data from the UI. If you got a integer in code behind, keep it there. Use it. But with the seperation between Events that might not be always possible.
I would recommend, do not just parse a text if you not know whats in the textbox.
Rather do something like this
if(double.TryParse (outputlbl.Text, out double outputNumber))
{
new Account(Nametxtbx.Text, outputNumber, 0);
}
Also, have a look at the formatprovider
I am trying to change textbox data on my program, but it isn't working.
The form is already shown but when I try it doesn't update.
I'm trying to use form1.show(); but my program is using multithreading and it spams windows in every thread.
What I tried so far is this.
Form1.CS code
private delegate void NameCallBack(string varText);
public void UpdateTextBox(string input)
{
if (InvokeRequired)
{
paidbox.BeginInvoke(new NameCallBack(UpdateTextBox), new object[] { input });
}
else
{
paidbox.Text = paidbox.Text + input;
// textBox.Text = textBox.Text + Environment.NewLine + input // This might work as append in next line but haven't tested so not sure
}
}
On my Program.CS I used on every bool I want it to be updated.
public static Form1 MainLogWindow = new Form1();
Cheker.MainLogWindow.UpdateTextBox("test test");
This isn't working, it compiles successfully but it doesn't update when the process start the text on textbox.
Sorry for my bad english.
P.S I'm new on C#, I know only php and javascript so this is so new to me.
I want to create a simple one time activation process for my windows form application. So, I basically have two forms, form1 is the activation window and form2 is the actual program. I've create a very basic activation program in form1 given below
string mac = textBox1.Text;
string str1 = mac.Substring(4,1);
string str2 = mac.Substring(5,1);
string str3 = mac.Substring(7,1);
string str4 = mac.Substring(2, 1);
string pattern = str1 + str2 + str2 + str3 + str4;
if (textBox2.Text == pattern)
{
MessageBox.Show("Program activated!!!");
Form2 n = new Form2();
n.Show();
this.Hide();
}
else { MessageBox.Show("Wrong key"); }
Now, the problem is every time I load my program it always loads form1 even when someone successfully entered the key(i.e. pattern) once before. How do I store that information so that if someone enters the correct key, every time after that whenever the program is loaded it will automatically show form2 (i.e. my actual program) and skip form1.
BTW, I'm aware that there are other more advanced and secure ways of doing this but I'm just currently interested in this very basic method.
Can anyone help?
Here's one very rudimentary way - write a file to a known location when they activate, then check for the existence of that file each time you load the form. If it's there, immediately show Form2. If not, give them the chance to activate.
Differing methods would be to save the activation status in the Registry or in a Database, or somewhere else, but the overall process is about the same
Sample code:
First, a method to get the path to the file we're going to create:
private string GetActivatedFilePath()
{
var appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
var thisExeName = Path.GetFileNameWithoutExtension(
System.Reflection.Assembly.GetEntryAssembly().Location);
return Path.Combine(appDataPath, thisExeName, "Activated.txt");
}
Then a couple of methods to create the file (Activate()), check if the file exists (IsActivated), and delete the file (Deactivate()):
private void Activate()
{
if (!IsActivated())
{
var filePath = GetActivatedFilePath();
Directory.CreateDirectory(Path.GetDirectoryName(filePath));
File.Create(filePath);
}
}
private bool IsActivated()
{
return File.Exists(this.GetActivatedFilePath());
}
private void Deactivate()
{
if (IsActivated())
{
File.Delete(GetActivatedFilePath());
}
}
Then we can also create a method to show the second form, since we will be calling this in more than one place. I've modified this to first hide the current form, then show the second form as a dialog (which means they can't switch back to the main form and code will pause in the first form until the second one closes), and then close the first form when the second one closes:
private void ShowForm2()
{
Form2 n = new Form2();
this.Hide();
n.ShowDialog();
this.Close();
}
Now we can check if they're activated in our Form_Load event, and if they are then immediately show the second form:
private void Form1_Load(object sender, EventArgs e)
{
// If they user is already activated, show the second form immediately
if (IsActivated())
{
ShowForm2();
}
}
And then your current code can also make use of these functions to activate the user. I'm assuming the code lives behind an Activate button:
private void btnActivate_Click(object sender, EventArgs e)
{
bool activated = false;
if (textBox1.Text.Length > 7)
{
string mac = textBox1.Text;
string str1 = mac.Substring(4, 1);
string str2 = mac.Substring(5, 1);
string str3 = mac.Substring(7, 1);
string str4 = mac.Substring(2, 1);
string pattern = str1 + str2 + str2 + str3 + str4;
activated = textBox2.Text == pattern;
}
if (activated)
{
MessageBox.Show("Program activated!!!");
Activate();
ShowForm2();
}
else
{
MessageBox.Show("Wrong key");
}
}
When I run my code, the line:
WriteLine("Saved Files " + saveFiles + "\n");
comes out before the other output lines preceding it. How can I fix this? Code is below.
Here is also a short video of me demonstrating what I mean too but the code is below. Full code here. Thanks so much.
using DemoMemento;
using System.Windows;
using static System.Diagnostics.Debug;
// This Memento patter will create a caretaker that contains the collection
// with all the Statements in it. It can add and
// retrieve Statements from the collection
namespace Memento
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
Caretaker caretaker = new Caretaker();
// The originator sets the value for the statement,
// creates a new memento with a new statement, and
// gets the statement stored in the current memento
Originator originator = new Originator();
int saveFiles = 0, currentStatement = -1;
// ---------------------------------------------
public MainWindow()
{
InitializeComponent();
}
private void btnSave_Click(object sender, RoutedEventArgs e)
{
// Get text in TextBox
string text = theStatement.Text;
// Set the value for the current memento
originator.set(text);
// Add new statement to the collection
caretaker.addMemento(originator.storeInMemento());
// saveFiles monitors how many statements are saved
// Number of mementos I have
saveFiles++;
currentStatement++;
WriteLine("Saved Files " + saveFiles + "\n");
btnUndo.IsEnabled = true;
}
private void btnUndo_Click(object sender, RoutedEventArgs e)
{
if (currentStatement >= 1)
{
currentStatement--;
string textBoxString = originator.restoreFromMemento(caretaker.getMemento(currentStatement));
theStatement.Text = textBoxString;
btnRedo.IsEnabled = true;
}
else {
btnUndo.IsEnabled = false;
}
}
private void btnRedo_Click(object sender, RoutedEventArgs e)
{
if ((saveFiles - 1)> currentStatement)
{
currentStatement++;
string textBoxString = originator.restoreFromMemento(caretaker.getMemento(currentStatement));
theStatement.Text = textBoxString;
btnUndo.IsEnabled = false;
}
else
{
btnRedo.IsEnabled = false;
}
btnUndo.IsEnabled = true;
}
}
}
The one output code uses Debug.WriteLine(), the others use Console.WriteLine(). These are two different ways of sending text to the output console which operate in parallel, asynchronously and independent of each other. Using Debug.WriteLine is usually faster than Console.WriteLine and wins the race unless you delay it by halting at a breakpoint before it is executed.
Debug.WriteLine is faster because it directly communicates with the Debugger, while Console.WriteLine takes a detour by writing into a pipe that the Debugger has to read from.
Imagine the difference between sending a letter and sending an email. The email arrives earlier than the letter even when it was sent some time after sending the letter.
Solution: Consistently only use Debug.WriteLine or only Console.WriteLine. Don't mix the two.
I have made a yatzy game in a console application, and I am currently trying to make one in a forms application.
This is what I have so far:
namespace Yatzy
{
public partial class Form1 : Form
{
public static Random kast = new Random();
public static int kast1 = kast.Next(1, 7);
public static int kast2 = kast.Next(1, 7);
public static int kast3 = kast.Next(1, 7);
public static int kast4 = kast.Next(1, 7);
public static int kast5 = kast.Next(1, 7);
public static int kast6 = kast.Next(1, 7);
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void pictureBox1_Click(object sender, EventArgs e)
{
if (kast1 == 1)
{
this.pictureBox_terning1.Image = new Bitmap(#"\Pics\terning1.png");
}
else if (kast1 == 2)
{
this.pictureBox_terning1.Image = new Bitmap(#"\Pics\terning2.png");
}
else if (kast1 == 3)
{
this.pictureBox_terning1.Image = new Bitmap(#"\Pics\terning3.png");
}
else if (kast1 == 4)
{
this.pictureBox_terning1.Image = new Bitmap(#"\Pics\terning4.png");
}
else if (kast1 == 5)
{
this.pictureBox_terning1.Image = new Bitmap(#"\Pics\terning5.png");
}
else if (kast1 == 6)
{
this.pictureBox_terning1.Image = new Bitmap(#"\Pics\terning6.png");
}
else
{
this.pictureBox_terning1.Image = new Bitmap(#"\Pics\terning0.png");
}
}
}
}
As you can see, I define the "kast1" and such in the form, and depending on the outcome, it should display different images in the picturebox. I have looked at every post I could find, and all of the solutions were fuss.
I have tried without "this." and I've tried with "= image.FromFile("Pics\terning#.png");"
Nothing works.
There is no need to use Bitmap object just to load images in the PictureBox.Perhaps the more cleaner way of loading images is by using the Load Method of PictureBox.
If I assume the images are in same directory as your application,enclosed in another folder,this would have done the job easily;
this.pictureBox_terning1.Load(#"\Pics\terning1.png");
The Load method requires a valid path that points to an image as argument,and with this there is no need to call Refresh after loading each image.It doesn't matter if the path is absolute or relative,but the thing that matters is that the path should point to an image.
But I would suggest you to create an absolute path to your executable like this;
string apppath=Application.StartupPath;
string imagepath=#"\Pics\terning1.png";
this.pictureBox_terning1.Load(apppath+imagepath);
As you mentioned that even if no errors are encountered,the images are not being loaded,for such a case debugging would be an ideal technique to find where the program runs out of order.
You probably need to call Refresh() on the picturebox control after you change picture source.
It is most likely that the images you want to load are not at the path you are looking at.
image.FromFile("Pics\terning#.png");
Expects that your images reside in {youprojectfolder}\bin\DebugORRelease\Pics.
new Bitmap(#"\Pics\terning1.png");
Expects that you images reside in {most likely c:}\Pics.
So i would suggest to check this first and if this does not work add a Breakpoint (F9) and start debugging (F5) see MSDN for an introduction in debugging
I would also suggest you to replace your if, else if construct with a switch.
Try this code, which I have tried and works(it will get the bin directory of your app then you can replace folders with image directory):
private void pictureBox1_Click(object sender, EventArgs e)
{
string path = AppDomain.CurrentDomain.BaseDirectory;
string path1 = path.Replace(#"\bin\Debug\", #"\Pics\");
if (kast1 == 1)
{
this.pictureBox_terning1.Image = new Bitmap(path1 + "terning1.png");
}
//rest of the code
}
And if you dont like replacing then set your pictures to be copied to bin directory by
right clicking on image -> properties -> Copy to output directory -> copy
always
.