return to main after paying - c#

i have POS system to fastfood, created by c# and sql server.
after the payment process show me window "Order Successfully Paid" after clicking to ok return to form ProductsReceiptPreview again,
i want after payment process go to the form main.
this is my code.......
private void lblPayments_Click(object sender, EventArgs e)
{
if (pnlPayments.Height != lbl.Height)
{
pnlPayments.Height = lbl.Height;
btnDone.Text = "DONE";
lbl.Text = "RECEIPT";
btnDone.Image = Resources.done;
Data.Show();
}
else
{
pnlPayments.Height = 394;
btnDone.Text = "RECEIPT";
lbl.Text = "AMOUNT";
btnDone.Image = Resources.receipt;
Data.Hide();
}
}
private void Touch_Click(object sender, EventArgs e)
{
var btn = (Button)sender;
txtCashReceived.Text += btn.Text;
}
private void btnClear_Click(object sender, EventArgs e)
{
if(txtCashReceived.Text.Length >0) txtCashReceived.Text =
txtCashReceived.Text.Remove(txtCashReceived.Text.Length - 1);
}
double totalBill = 0;
private void btnPay_Click(object sender, EventArgs e)
{
if (txtCashReceived.Text.Length > 0 && totalBill <=
Convert.ToInt32(txtCashReceived.Text) && Data.RowCount > 0)
{
int i = 0;
foreach (var rep in ListReports)
{
i++;
var report = new ModelReports();
report.Productname = rep.Productname;
report.TotalSales = rep.TotalSales;
report.TotalTransactions = rep.TotalTransactions;
report.Save();
}
var rpd = new ProductsReceiptPreview(dataReceiptBindingSource,
txtTotal.Text, txtCashReceived.Text, txtChange.Text);
rpd.ShowDialog();
if (i == ListReports.Count)
{
MessageBox.Show("Order Successfully Paid");
}
pnlProducts.Controls.Clear();
pnlCategoryPanel.Visible = false;
dataReceiptBindingSource.Clear();
LoadTables();
btnDone.PerformClick();
}
else
{
MessageBox.Show("Please pay your order.");
txtCashReceived.Text = "0";
}
}
private void btnPay_Click_1(object sender, EventArgs e)
{
if (txtCashReceived.Text.Length > 0 && totalBill <=
Convert.ToInt32(txtCashReceived.Text) && Data.RowCount > 0)
{
int i = 0;
foreach (var rep in ListReports)
{
i++;
var report = new ModelReports();
report.Productname = rep.Productname;
report.TotalSales = rep.TotalSales;
report.TotalTransactions = rep.TotalTransactions;
report.Save();
}
if (i == ListReports.Count)
{
MessageBox.Show("Order Successfully Paid");
txtCashReceived.Text = "0";
}
pnlProducts.Controls.Clear();
pnlCategoryPanel.Visible = false;
dataReceiptBindingSource.Clear();
LoadTables();
btnDone.PerformClick();
}
else
{
MessageBox.Show("Please pay your order.");
}
}

If you call some code from main then it will return to main when the call is finished. In the case of a Form, it's handled on a different thread started from main. The thread will never return back to main in this context. If you are using a click event to do some action and want to call some other code when that happens, then you need to re-design your infrastructure. Look into SOLID development principles and dependency injection.
https://www.codeproject.com/Tips/1033646/SOLID-Principle-with-Csharp-Example
https://simpleinjector.readthedocs.io/en/latest/windowsformsintegration.html

Related

c# Flappybird "Non-invocable member cannot be used like a method"

I'm trying to re-create flappybird in Visual studio 2015 c# for a little school project. But for some reason i get this error that i really can't fix. I'm following an tutorial on how to create flappybird, but the one making the tutorial is writing in VB.net Heres the YT Link and under that my code I'm trying to make.
https://www.youtube.com/watch?v=tnjdMbdEzMo
public partial class Form10 : Form
{
int gravity = 1;
int yspeed = 0;
PictureBox[,] Pipe;
public Form10()
{
InitializeComponent();
}
private void gameTimer_Tick(object sender, EventArgs e)
{
int i;
this.yspeed += this.gravity;
bird.Top += this.yspeed;
}
private void inGameKeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Space)
{
this.yspeed = -15;
}
}
private void pausePlayToolStripMenuItem_Click(object sender, EventArgs e)
{
if (gameTimer.Enabled == true)
{
gameTimer.Enabled = false;
}
else
{
if (gameTimer.Enabled == false)
{
gameTimer.Enabled = true;
}
}
}
private void restartToolStripMenuItem_Click(object sender, EventArgs e)
{
}
private void startGame_Click(object sender, EventArgs e)
{
if (gameTimer.Enabled == false)
{
gameTimer.Enabled = true;
startGame.Enabled = false;
}
}
private void CreatePipes(int number)
{
int i = 0;
for (i = 0; (i <= number); i++)
{
var temp = new PictureBox();
this.Controls.Add(temp);
temp.Width = 50;
temp.Height = 370;
temp.BorderStyle = BorderStyle.FixedSingle;
temp.BackColor = Color.Red;
temp.Top = 50;
temp.Left = (2 * 200) + 300;
Pipe(i) = temp;
Pipe(i).Visable = true;
}
}
private void Form10_Load(object sender, EventArgs e)
{
gameTimer.Enabled = true;
CreatePipes(1);
}
}
}
The problem you are seeing is in the lines
Pipe(i) = temp;
Pipe(i).Visable = true;
If you are trying to access Pipe as an array, the syntax is Pipe[i], although pipe is a 2d array so it should be Pipe[i,j] Where j is something else.
Also you have misspelled Visible.

Change Label's Text when Button is clicked

I am new to C#. I need the text of lblBalance to remain as it is when the btnNew is clicked, while it changes according to some calculatios when btnCalc is clicked. Here is my attempt so far.
FIGURED IT OUT, Thanks!
private void btnReset_Click(object sender, EventArgs e)
{
//Reset balance to 0.
balance = 0m;
lblBalance.Text = "";
tbDate.Text = "";
//Call the setupForm procedure.
setupForm();
}
private void setupForm()
{
//Setupform done once to reduce amount of times code must be entered.
//Code to clear these entries and set radio and checkboxes to false.
tbDate.Text = "";
tbAmount.Text = "";
rDeposit.Checked = false;
rWithdrawal.Checked = false;
rFee.Checked = false;
chkBank.Checked = false;
//Return focus to the date textbox
tbDate.Focus();
}
private void btnNew_Click(object sender, EventArgs e)
{
//Clear form, but retain balance when clicked.
setupForm();
}
private void tbDate_TextChanged(object sender, EventArgs e)
{
}
private void lblBalance_Click(object sender, EventArgs e)
{
}
private void btnCalc_Click(object sender, EventArgs e)
{
decimal Amount;
Amount = decimal.Parse(tbAmount.Text);
if ((rDeposit.Checked == true) && (chkBank.Checked == true))
{
Decimal.TryParse(lblBalance.Text, out balance);
lblBalance.Text = Convert.ToString(balance + Amount);
}
else if ((rWithdrawal.Checked == true) && (chkBank.Checked == true))
{
Decimal.TryParse(lblBalance.Text, out balance);
lblBalance.Text = Convert.ToString(balance - Amount);
}
else if ((rFee.Checked == true) && (chkBank.Checked == true))
{
Decimal.TryParse(lblBalance.Text, out balance);
lblBalance.Text = Convert.ToString(balance - Amount);
}
if ((rDeposit.Checked == false) && (rWithdrawal.Checked == false) && (rFee.Checked == false))
{
MessageBox.Show("ERROR: You must select Deposit, Withdrawal, or Service Fee.");
}
}
private void rDeposit_CheckedChanged(object sender, EventArgs e)
{
}
}
}
change:
lblBalance.Text += balance.ToString();
to
lblBalance.Text = balance.ToString();
Inside your btnNew_Click event

XO game using c# and ASP.NET

i'm new to C# (and programming at all) and i'm trying to write an 'XO' game along with ASP.NET
i'm getting a problem after the first player clicks a button.
turns doesn't switch and any click after the 1st does nothing. what is wrong with my code ?
public partial class GamePage : System.Web.UI.Page
{
Player player1 = new Player();
Player player2 = new Player();
int turn;
protected void Page_Load(object sender, EventArgs e)
{
this.turn = 0;
if (!IsPostBack)
{
Label1.Visible = true;
}
if (turn == 0)
{
Label1.Text = (Session["player1"] as Player).getname();
}
else
{
Label1.Text = (Session["player2"] as Player).getname();
}
}
protected void Button1_Click(object sender, EventArgs e)
{
Session["p1"] = player1;
Session["p2"] = player2;
player1.setsymbol("X");
player2.setsymbol("O");
if (Button1.Text == "")
{
if (turn == 0)
{
Button1.Text = player1.getsymbol();
Label1.Text = (Session["player2"] as Player).getname();
turn = 1;
}
else
{
Button1.Text = player2.getsymbol();
Label1.Text = (Session["player1"] as Player).getname();
turn = 0;
}
}
}
protected void Button2_Click(object sender, EventArgs e)
{
if (Button2.Text == "")
{
if (turn == 0)
{
Button2.Text = player1.getsymbol();
Label1.Text = (Session["player2"] as Player).getname();
turn = 1;
}
else
{
Button2.Text = player2.getsymbol();
Label1.Text = (Session["player1"] as Player).getname();
turn = 0;
}
}
}
protected void Button3_Click(object sender, EventArgs e)
{
if (Button3.Text == "")
{
if (turn == 0)
{
Button3.Text = player1.getsymbol();
Label1.Text = (Session["player2"] as Player).getname();
turn = 1;
}
else
{
Button3.Text = player2.getsymbol();
Label1.Text = (Session["player1"] as Player).getname();
turn = 0;
}
}
}
// this is an example - i have the same lines from button1 to 9
Everytime page renders, you set turn to 0 in Page_Load. Because Page_Load is executed upon every page load, you won't get any other value and this is probably the major issue here.
To properly support the lifetime of such variables that should keep value upon consecutive requests, wrap them in simple property:
public int turn
{
get
{
if ( Session["turn"] != null )
return (int)Session["turn"];
return 0; // default value if not set before
}
set
{
Session["turn"] = value;
}
}
This way everytime you refer to turn in your code, setting it to 0 or 1 or comparing the value to 0 or 1, you will refer to the same value, possibly stored during previous request(s).
this.turn=0; should be executed only when IsPostBack is false. Move this line inside if in your Page_Load.

Two simultaneous Textchanged Events firing in Winforms C#

When I type in the first textbox, it should run a conversion which appears in the second, and when I type in the second, it will appear in the first. However, when I type in the first textchanged event, it triggers the second, which disrupts entering in the first and vice versa. Is there a way I can disable firing the textchanged event when it is highlighted or something?
public void dB10_TextChanged(object sender, EventArgs e)
{
TextBox dB10 = sender as TextBox;
double dBV;
int i = dB10.Text.Trim().Length;
if (i > 0)
{
dBV = Convert.ToDouble(dB10.Text);
}
else
return;
UnitConverter dBConverter = new UnitConverter();
// Controls for if various radiobuttons were clicked
if (dBVRadio.Checked == true)
{
dBV = dBConverter.dBVToVolts(dBV);
voltage.Text = dBV.ToString();
}
else if (dBuRadio.Checked == true)
{
dBV = dBConverter.dBuToVolts(dBV);
voltage.Text = dBV.ToString();
}
}
public void voltage_TextChanged(object sender, EventArgs e)
{
TextBox voltage = sender as TextBox; //V >> dB10 (dBV/dBu)
int i = voltage.Text.Trim().Length;
double volts;
if (i > 0)
{
volts = Convert.ToDouble(voltage.Text);
}
else
return;
UnitConverter dBConverter = new UnitConverter();
if (dBVRadio.Checked == true)
{
dBuRadio.Checked = false;
volts = dBConverter.voltsTodBV(volts);
dB10.Text = volts.ToString();
}
else if (dBuRadio.Checked == true)
{
volts = dBConverter.voltsTodBu(volts);
dB10.Text = volts.ToString();
}
}
you can remove the handler of another textbox and then add it
public void dB10_TextChanged(object sender, EventArgs e)
{
voltage.TextChanged-= voltage_TextChanged;
TextBox dB10 = sender as TextBox;
double dBV;
int i = dB10.Text.Trim().Length;
if (i > 0)
{
dBV = Convert.ToDouble(dB10.Text);
}
else
return;
UnitConverter dBConverter = new UnitConverter();
// Controls for if various radiobuttons were clicked
if (dBVRadio.Checked == true)
{
dBV = dBConverter.dBVToVolts(dBV);
}
else if (dBuRadio.Checked == true)
{
dBV = dBConverter.dBuToVolts(dBV);
}
voltage.Text = dBV.ToString();
voltage.TextChanged+= voltage_TextChanged;
}
You can just use a bool variable:
bool escape = false;
public void dB10_TextChanged(object sender, EventArgs e)
{
if(escape)
return;
escape = true;
// your code
escape = false;
}
public void voltage_TextChanged(object sender, EventArgs e)
{
if(escape)
return;
escape = true;
// your code
escape = false;
}

BackgroundWorker for implementing "Search as you type" Combobox

I have created a code for my combobox, that can search addresses in a very large table on Sql Server with the help of stored procedure (i'm working with Entity framework). My stored procedure returns 10 hits and my code fills the combobox with search results. For doing this I'm using BackgroundWorker.
But here I'm now having big problems:
- although the combobox is filled with my search results, it always has the first item selected. Even if I type in only a letter, the whole text gets selected;
After that searching for the address doesn't work anymore. It searches only among these 10 results and I'm having no idea how to solve this. Here is my whole code, that causes me problems:
public String searchedItem = "";
public delegate void DelegateUpdateComboboxSelection(ComboBox myCombo,string value,int count);
BackgroundWorker m_bgworker = new BackgroundWorker();
static AutoResetEvent resetWorker = new AutoResetEvent(false);
m_bgworker.WorkerSupportsCancellation = true;
m_bgworker.DoWork += new DoWorkEventHandler(FillComboboxBindingList);
m_bgworker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(m_bgworker_RunWorkerCompleted);
BindingList<spIskalnikNaslovi_Result1> m_addresses = new BindingList<SP_Result1>();
void m_bgworker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
int count = (int)((object[])e.Result)[0];
string value = (string)((object[])e.Result)[1];
ComboBox myCombo = (ComboBox)((object[])e.Result)[2];
DelegateUpdateComboboxSelection ndelegate = new DelegateUpdateComboboxSelection(UpdateComboSelection);
if (this.InvokeRequired)
{
Invoke(ndelegate, new object[] {myCombo, value, count});
return;
}
else
{
UpdateComboSelection(myCombo, value, count);
return;
}
}
private void UpdateComboSelection(ComboBox myCombo, String value, int count)
{
myCombo = comboBox9;
myCombo.DataSource = m_addresses;
searchedItem = myCombo.Text;
if (count > 0)
{
myCombo.SelectionStart = value.Length;
myCombo.SelectionLength = searchedItem.Length - value.Length;
myCombo.DroppedDown = true;
}
else
{
myCombo.DroppedDown = false;
myCombo.SelectionStart = value.Length;
}
}
public void FillComboboxBindingList(object sender, DoWorkEventArgs e)
{
if (m_bgworker.CancellationPending)
{
resetWorker.Set();
e.Cancel = true;
return;
}
else
{
string value = (String)((Object[])e.Argument)[0];
List<SP_Result1> result;
result = _vsebina.SP_searcher(value).ToList<SP_Result1>();
m_addresses = new BindingList<SP_Result1>();
foreach (SP_Result1 rez in result)
{
if (m_addresses.Contains(rez))
{
continue;
}
else
{
m_addresses.Add(rez);
}
}
foreach (SP_Result1 r in m_addresses.ToArray())
{
if (!result.Contains(r))
{
m_addresses.Remove(r);
}
}
e.Result = new object[] { rezultat.Count, vrednost, null };
return;
}
}
private void comboBox9_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Back)
{
int searchStart = comboBox9.SelectionStart;
if (searchStart > 0)
{
searchStart--;
if (searchStart == 0)
{
comboBox9.Text = "";
}
else
{
comboBox9.Text = comboBox9.Text.Substring(0, searchStart + 1);
}
}
else
{
searchStart = 0;
}
e.Handled = true;
}
}
private void comboBox9_Enter(object sender, EventArgs e)
{
comboBox9.SelectionStart = 0;
comboBox9.SelectionLength = 0;
}
private void comboBox9_Click(object sender, EventArgs e)
{
comboBox9.Text = "";
}
private void comboBox9_KeyPress(object sender, KeyPressEventArgs e)
{
Search();
}
public void Search()
{
if (comboBox9.Text.Length < 4)
{
return;
}
else
{
if (m_bgworker.IsBusy)
{
m_bgworker.CancelAsync();
m_bgworker = new BackgroundWorker();
m_bgworker.WorkerSupportsCancellation = true;
m_bgworker.DoWork += new DoWorkEventHandler(FillComboboxBindingList);
m_bgworker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(m_bgworker_RunWorkerCompleted);
}
m_bgworker.RunWorkerAsync(new object[] { comboBox9.Text, comboBox9 });
}
}
Maybe can someone enlighten me, what I'm doing wrong. This is first time, that I'm using BackgroundWorker. I have no idea, how
to achieve "search as you type" with combobox in any other way, because my datatable with addresses is quite large (million records).
Thanks in advance for any kind of help or code example.
Vladimir
Edit 1:
Ok, here is my code, before I have used BackGroundWorker. It worked, but it searches very very slow (it can take up to 10 seconds):
private void comboBox9_TextChanged(object sender, EventArgs e)
{
if (comboBox9.Text.Length < 4)
{
return;
}
else
{
FillCombobox(comboBox9.Text, comboBox9);
}
}
public void FillCombobox(string value, ComboBox myCombo)
{
List<spIskalnikNaslovi_Result1> result;
result = _vsebina.spIskalnikNaslovi1(value).ToList();
if (result.Count() > 0)
{
myCombo.DataSource = result;
myCombo.ValueMember = "HS_MID";
myCombo.DisplayMember = "NASLOV1";
var searchedItem = myCombo.Items[0].ToString();
myCombo.SelectionStart = value.Length;
myCombo.SelectionLength = searchedItem.Length - value.Length;
myCombo.DroppedDown = true;
}
else
{
myCombo.DroppedDown = false;
myCombo.SelectionStart = value.Length;
}
return;
}
Is there a way to speed this up without having backgroundworker?
make a button you will call searchbutton
and in click_event of this button call your search() method that run your backgroundworker
that fill the combobox
clear you key_press event of your combobox and it will work
the mistake is you key_press event that call every key stroke happening your search method
so retrieve it
You should get your items in a list, use that list to populate your combobox.
then set AutoCompleteMode property value to Suggest or Append or SuggestAppend and set AutoCompleteSoucre property value to ListItems.
For "Search as you Type", which is actually "Filter as you Type" more than search, you need to implement the OnKeyDown or KeyPressed event.
What you would do is take the search string, which is the current text at the time of the event, then filter the master list using that string. Normally one would use "Starts With" for the filtering, but you could also simply use "Contains". Then you live update the contents of the box with the results from the filter. This is accomplished by changing and refreshing the Datasource.
Here is my final solution without BackGroundWorker. It works quick with my large table, and is upgraded for using a stored procedure on SQL Server (if you use Entity Framework). I use Timer to make sure the user can find a value, that he is searching.
Here you can see the original solution, that I found on this site (thanks to Max Lambertini and algreat for the idea and working concept):
C# winforms combobox dynamic autocomplete
My solution:
private bool _canUpdate = true;
private bool _needUpdate = false;
List<spIskalnikNaslovi_Result1> dataFound;
private void comboBox12_TextChanged(object sender, EventArgs e)
{
if (_needUpdate)
{
if (_canUpdate)
{
_canUpdate = false;
refreshData();
}
else
{
restartTimer();
}
}
}
private void comboBox12_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Back)
{
int searchStart = comboBox12.SelectionStart;
if (searchStart > 0)
{
searchStart--;
if (searchStart == 0)
{
comboBox12.Text = "";
}
else
{
comboBox12.Text = comboBox12.Text.Substring(0, searchStart + 1);
}
}
else
{
searchStart = 0;
}
e.Handled = true;
}
}
private void comboBox12_TextUpdate(object sender, EventArgs e)
{
_needUpdate = true;
}
private void timer1_Tick(object sender, EventArgs e)
{
_canUpdate = true;
timer1.Stop();
refreshData();
}
private void refreshData()
{
if (comboBox12.Text.Length > 1)
{
FillCombobox(comboBox12.Text, comboBox12);
}
}
private void restartTimer()
{
timer1.Stop();
_canUpdate = false;
timer1.Start();
}
private void FillCombobox(string value, ComboBox myCombo)
{
dataFound = _vsebina.spIskalnikNaslovi1(value).ToList();
if (dataFound.Count() > 0)
{
myCombo.DataSource = dataFound;
myCombo.ValueMember = "HS_MID";
myCombo.DisplayMember = "NASLOV1";
var searchedItem = myCombo.Items[0].ToString();
myCombo.SelectionStart = value.Length;
myCombo.SelectionLength = searchedItem.Length - value.Length;
myCombo.DroppedDown = true;
return;
}
else
{
myCombo.DroppedDown = false;
myCombo.SelectionStart = value.Length;
return;
}
}

Categories