Re-Enabling Button Based on Condition (C#) - c#

What I am trying to do is simple (I cannot figure it out of course). I am making a sample shop with an inventory system in Winform App format where if on the customer side the "Place Order" button is clicked it deducts from inventory; the amount deducted depends on the quantity of the item ordered. Anyway with this code,
private void button7_Click(object sender, EventArgs e)
button7.Enabled = true;
//Read in value
int qty = Convert.ToInt32(nudQuantity.Value);
if ((rdoSmallCup.Checked & rdoStraw.Checked) == true) {
//Removing four from inventory for strawberry after an order is made
InvStrawberry = InvStrawberry - (4 * qty);
if (InvStrawberry <= 0) {
button7.Enabled = false;
} else {
button7.Enabled = true;
}
label17.Text = Convert.ToString(InvStrawberry);
I am seeing that while it does compile with no errors once the inventory for strawberry has fallen past zero (it will actually be a negative value which I do not want but is another question for another time) the Place Order button ("Button 7") will be grayed out and unusable which is the goal but once inventory is added again this button is still unusable. Can someone explain how I can have this button re-enabled (even though I said it in the 'else' condition)?

Ron and Heretic's comments are right. You cannot access the code in Button7 click event handler once it has been 'disabled'. The only way to enable it again is from outside logic, say after you added additional items into the inventory, you can enable the button right after that.
Also you can can be simplify a bit:
private void button7_Click(object sender, EventArgs e)
//Read in value
int qty = Convert.ToInt32(nudQuantity.Value);
if ((rdoSmallCup.Checked & rdoStraw.Checked) == true) {
//Removing four from inventory for strawberry after an order is made
InvStrawberry = InvStrawberry - (4 * qty);
if (InvStrawberry <= 0)
button7.Enabled = false;
label17.Text = Convert.ToString(InvStrawberry);
...

This code will allow an infinite number of subtraction. Hence, you will need a control that will stop the subtraction when you go below zero.
private void button7_Click(object sender, EventArgs e){
// I have no idea why you have enabled the button here, mate
//Converting the quantity
int qty = Convert.ToInt32(nudQuantity.Value);
if((roSmallCup.Checked & rdoStraw.Checked) == true) {
//triggers when the Inventory of strawberry is more than zero
if( (InvStrawberry - (4 * qty)) > 0 ){
InvStrawberry = InvStrawberry - (4 * qty);
} else
{
button7.ENabled = false;
MessageBox.Show("We are out of inventory,Sorry!");
}
label17.Text = Convert.ToString(InvStrawberry);
}
}

If you want the button to possibly update every time that you change the value of InvStrawberry then the best option is to make a property for InvStrawberry and update the status of the button there. That cuts down the logic that you need to use right throughout your code.
Try this:
public class StrawberryForm : Form
{
private int _invStrawberry = 0;
private int InvStrawberry
{
get
{
return _invStrawberry;
}
set
{
_invStrawberry = value;
button7.Enabled = _invStrawberry > 0;
}
}
private void button7_Click(object sender, EventArgs e)
{
int qty = Convert.ToInt32(nudQuantity.Value);
if ((rdoSmallCup.Checked & rdoStraw.Checked) == true)
{
this.InvStrawberry -= 4 * qty;
label17.Text = Convert.ToString(this.InvStrawberry);
}
}
}

you need to move this:
if (InvStrawberry <= 0) {
button7.Enabled = false;
} else {
button7.Enabled = true;
}
to an Updae method or loop that will check it regularly, right now its in your click, and therefore will never get called to enable it again once it is disabled, since at that point you cant click on it.
also, say you have two variables, numberStrawberries representing youre remaining inventory, and lot representing the four strawberries you put in a purchase...
if(numberStrawberries >= lot){
//we have strawberries, and more at least 4 or more
numberStrawberries-=lot;
}else if(numberStrawberries!=0 && numberStrawberries < lot){
//we have strawberries but only (remaining)
//how many were short(how many we have is still in numberStrawberries)
int short = lot- numberStrawberries;
numberStrawberries=0;
}else{
//all out of strawberries
}

Related

Creating a meal Cost calculator C#

I'm trying to create a Meal Cost Calculator using C#.
Here is my current code
public partial class Form1 : Form
{
const double TAX_RATE = .076;
const double EXTRA_DISCOUNT = .1;
public Form1()
{
InitializeComponent();
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
private void tiplistBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if ((lessThanButton.Checked == true) && (moreThanButton.Checked == false)) ;
{
int selectedIndex = tiplistBox1.SelectedIndex;
switch (selectedIndex)
{
case 1:
break;
}
}
}
private void calculateButton_Click(object sender, EventArgs e)
{
int mealCost = int.Parse(mealCostBox1.Text);
double tax = (mealCost * TAX_RATE) + mealCost;
double disc = (tax * EXTRA_DISCOUNT);
double tipRate = (tax - disc);
double totalCost = (tipRate);
}
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
int count = 1;
if ((lessThanButton.Checked == true) && (moreThanButton.Checked == false))
{
tiplistBox1.Items.Add("");
for (count = 10; count <= 35; count += 5)
tiplistBox1.Items.Add("Tip Rate: " + count + "%");
count++;
}
}
private void radioButton2_CheckedChanged(object sender, EventArgs e)
{
int count = 1;
if ((lessThanButton.Checked == false) && (moreThanButton.Checked == true))
{
tiplistBox1.Items.Add("");
for (count = 15; count <= 35; count += 5)
tiplistBox1.Items.Add("Tip Rate: " + count + "%");
count++;
}
}
}
The user must enter the amount of the meal.
Then the user selects a radio button that asks how many people ate. (one RB is for less than 6 and the other is for more than 6.) this button is used in order to give tip rates which are displayed in tiplistBox1 (if <6 ppl = 10,15,20,25,30,35, if >6 ppl 15,20,25,30,35) The user must also identify if there is any type of discount, which is selected from checking one of three boxes (student, military or senior) if either one is selected a 10% discount is added. Once all is selected the calculate button is supposed to take the mealCost add the TAX_RATE, take any discounts off and if a tip rate is selected from the tiplistBox1 options, add the tipRate then give the amount due.
Right now, my project isn't complete, there are a few issues, first of all, as you can see, I'm not using the If,Else statements, I'm required to use switch statements, when I'm running the program from the start I'm getting the tipRate's to display correctly for example, if I select the RB that is <6 people, then the tipRates shown are 10,15,20,25,30,35. If instead, from the start I select RB that is >6 people then the tipRates 15,20,25,30,35 are shown. That's good, but when I try to switch the RB within the ongoing program the TipRates get added underneath the first set of tipRates
, also since I'm using switch statements, if I select either of the RB, the displayed tipRates don't match up, meaning if I create a case 1: in one instance it shows 10% but in another is shows 15%, which messes with the calculation process.
I need help!
How can I ensure that the tipRate selected will make sence in the calculation.
for example if in case 1: it shows 15% but only does the math for 10% tipRate.
...but when I try to switch the RB within the ongoing program the TipRates get added underneath the first set of tipRates
That's because you need to clear the list before adding the new set of rates to the list.
Call tiplistBox1.Items.Clear() before calling tiplistBox1.Items.Add("").

Is There A Better Way To Force Scrollbar Values To Certain Increments & Bind Values To A Textbox (C#)?

I have a setting in my application that requires any value between 24 and 65520 that must be evenly divisible by 24. I decided to implement this with a horizontal scrollbar and a textbox that shows the current value of the scrollbar, and can have a value manually typed into it (which then sets the scrollbar value). The scrollbar has minimum = 24, maximum = 65520, small & large increments = 1. The default value at app launch is 960. I ended up having to use a couple of event handlers for both the textbox and the scrollbar, and even still it didn't work perfectly. My first mostly-working attempt was this:
private void hScrollBar_TicksPerQuarter_Scroll(object sender, ScrollEventArgs e)
{
int NewValue = e.NewValue;
if (e.Type != ScrollEventType.EndScroll)
{
if (e.NewValue < e.OldValue)
{
NewValue = e.NewValue - (e.NewValue % 24);
}
else if (e.NewValue > e.OldValue)
{
NewValue = e.NewValue + (e.NewValue % 24 == 0 ? 0 : 24 - (e.NewValue % 24));
}
txtTicksPerQuarter.Text = NewValue.ToString();
}
else
{
hScrollBar_TicksPerQuarter.Value = NewValue;
}
}
private void hScrollBar_TicksPerQuarter_ValueChanged(object sender, EventArgs e)
{
if (hScrollBar_TicksPerQuarter.Value.ToString() != txtTicksPerQuarter.Text)
{
hScrollBar_TicksPerQuarter.Value = Convert.ToInt32(txtTicksPerQuarter.Text);
}
}
private void txtTicksPerQuarter_Leave(object sender, EventArgs e)
{
TrySetTicksPerQuarter();
}
private void txtTicksPerQuarter_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
TrySetTicksPerQuarter();
}
private void TrySetTicksPerQuarter()
{
bool useOldValue = false;
int TicksPerQuarter_OldValue = hScrollBar_TicksPerQuarter.Value;
int TicksPerQuarter = 0;
if (Int32.TryParse(txtTicksPerQuarter.Text, out TicksPerQuarter))
{
if (TicksPerQuarter % 24 == 0)
{
hScrollBar_TicksPerQuarter.Value = TicksPerQuarter;
}
else
{
useOldValue = true;
MessageBox.Show("Must enter a value that is a multiple of 24, with a minimum of 24 and a maximum of 65520.", "Invalid TicksPerQuarter", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
else
{
useOldValue = true;
}
if (useOldValue)
txtTicksPerQuarter.Text = TicksPerQuarter_OldValue.ToString();
}
This works fairly well, if I enter a value in the textbox and leave the box or press Enter, it will update the scrollbar accordingly, and if the value is not a proper multiple of 24 it will just reset itself to the last valid value and display a message to the user indicating the issue. Scrolling the scrollbar updates the textbox in real time as you scroll, and everything basically works. The problem is that when you click and drag the scrollbar, the moment you let results in a jump in the value (usually of a couple hundred or so, in either direction). Not sure why it was happening, I started experimenting with changes the "Scroll" event on the scrollbar to see if I could fix it, so releasing the scrollbar after dragging it would result in the value staying what it displayed at the time you release it. It took a lot of experimentation, including some drastic overhauls to everything that didn't even work as well as the code I put above, but ultimately the best I could get was to keep all the code above the same in the other events, and just change the Scroll event to this:
ScrollEventType[] IncrementScrollEvents = new ScrollEventType[] { ScrollEventType.LargeIncrement, ScrollEventType.SmallIncrement, ScrollEventType.Last };
ScrollEventType[] DecrementScrollEvents = new ScrollEventType[] { ScrollEventType.LargeDecrement, ScrollEventType.SmallDecrement, ScrollEventType.First };
private void hScrollBar_TicksPerQuarter_Scroll(object sender, ScrollEventArgs e)
{
int NewValue = e.NewValue;
if (IncrementScrollEvents.Contains(e.Type))
{
NewValue = e.NewValue + (e.NewValue % 24 == 0 ? 0 : 24 - (e.NewValue % 24));
}
else if (DecrementScrollEvents.Contains(e.Type))
{
NewValue = e.NewValue - (e.NewValue % 24);
}
else if (e.Type == ScrollEventType.ThumbTrack)
{
if (e.NewValue < e.OldValue)
{
NewValue = e.NewValue - (e.NewValue % 24);
}
else if (e.NewValue > e.OldValue)
{
NewValue = e.NewValue + (e.NewValue % 24 == 0 ? 0 : 24 - (e.NewValue % 24));
}
}
else if (e.Type == ScrollEventType.EndScroll)
{
hScrollBar_TicksPerQuarter.Value = NewValue;
}
else
{
return;
}
txtTicksPerQuarter.Text = NewValue.ToString();
}
This definitely works better, and if I had to estimate it, I'd say maybe 4 out of 5 times you release the scrollbar, the value remains where it was at the last moment before you let go of the mouse button. But it still isn't perfect.
I was hoping there is a better way to do this, both in terms of functionality being just that little bit more perfect than it is now, and perhaps even in terms of the overall complexity of the code. I didn't expect to have to write code in 4 different events across 2 controls to do this, but perhaps there isn't a better way after all?
EDIT 1:
I had an idea to use increments of 1 and min/max 1-2730 instead of 24-65520 and then instead of doing math and verification and manually setting the value of the scrollbar to ensure it's a multiple of 24, I will instead just multiply its real value by 24 to get the usable value and the display value for the textbox. This code is now identical in functionality to what I had above, with a lot less complexity. I also moved the warning messagebox for invalid entry in the textbox so that it displays a message even when the user types something that can't even be converted to an integer:
private void hScrollBar_TicksPerQuarter_Scroll(object sender, ScrollEventArgs e)
{
txtTicksPerQuarter.Text = (e.NewValue * 24).ToString();
}
private void txtTicksPerQuarter_Leave(object sender, EventArgs e)
{
TrySetTicksPerQuarter();
}
private void txtTicksPerQuarter_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
TrySetTicksPerQuarter();
}
private void TrySetTicksPerQuarter()
{
bool useOldValue = false;
int TicksPerQuarter_OldValue = hScrollBar_TicksPerQuarter.Value;
int TicksPerQuarter = 0;
if (Int32.TryParse(txtTicksPerQuarter.Text, out TicksPerQuarter))
{
if (TicksPerQuarter % 24 == 0)
{
hScrollBar_TicksPerQuarter.Value = (TicksPerQuarter / 24);
}
else
{
useOldValue = true;
}
}
else
{
useOldValue = true;
}
if (useOldValue)
{
MessageBox.Show("Must enter a value that is a multiple of 24, with a minimum of 24 and a maximum of 65520.", "Invalid TicksPerQuarter", MessageBoxButtons.OK, MessageBoxIcon.Warning);
txtTicksPerQuarter.Text = (TicksPerQuarter_OldValue * 24).ToString();
}
}
The scrollbar still jumps occasionally when you let go of the mouse button when you're dragging it left and right. I still don't have a solution for that particular problem, unless it's really not something that I can fix due to the way the mouse and scroll bar play with each other?
I just made a small WinForms demo app using just a single scrollbar (hScrollbar1) and a label (Label1).
Created the form's Load event handler and added the following code:
hScrollBar1.Minimum = 1;
hScrollBar1.Maximum = 65520 / 24;
hScrollBar1.Value = 960 / 24;
hScrollBar1.LargeChange = 1;
Created hScrollBar1's ValueChanged event handler and added the following code:
label1.Text = (hScrollBar1.Value * 24).ToString();
Seems to work fine for me this way. Not sure if I could get it to work when using stepping values of 24 in the scrollbar property settings... Sorry for that...
Edit: Just saw your own comment. I agree. :)

C# Calculator with memory buttons

I am having some difficulties making my calculator have the ability to store values. The calculator works for everything except this and I am quite stuck. I think I might have to declare some constants or something that I am missing right now. I am super new at this and appreciate the help. Here is my code. Thanks for any help guys. Right now I am getting no errors but nothing works either! I am also supposed to make it so a "M" appears in a textbox when there is a value stored in memory but I figured it was easier to start with this part.
private void digitCalculate_Click(object sender, EventArgs e)
{
Button ButtonThatWasPushed = (Button)sender;
string ButtonText = ButtonThatWasPushed.Text;
decimal EndResult = 0;
decimal MemoryStore = 0;
if (ButtonText == "MC")
{
//Memory Clear
MemoryStore = 0;
return;
}
if (ButtonText == "MR")
{
//Memory Recall
txtDisplay.Text = MemoryStore.ToString();
return;
}
if (ButtonText == "MS")
{
// Memory subtract
MemoryStore -= EndResult;
return;
}
if (ButtonText == "M+")
{
// Memory add
MemoryStore += EndResult;
return;
}
}
You need to have Form level variable for decimal MemoryStore = 0; , since you have function level variable it will initialized to 0 when you click on digitCalculate button
decimal MemoryStore = 0;
decimal EndResult = 0;
public Form1()
{
InitializeComponent();
}
private void digitCalculate_Click(object sender, EventArgs e)
{
Button ButtonThatWasPushed = (Button)sender;
string ButtonText = ButtonThatWasPushed.Text;
//decimal EndResult = 0;
//decimal MemoryStore = 0;
And also note that
MC = Memory Clear sets the memory to 0
MR = Memory Recall uses the
number in memory
MS = Memory Store puts the number on the display into the memory
You nee to change "MS" logic and add "M-"
if (ButtonText == "MS")
{
MemoryStore = Decimal.Parse(txtDisplay.Text);
return;
}
if (ButtonText == "M-")
{
// Memory subtract
MemoryStore -= EndResult;
txtDisplay.Text = MemoryStore.ToString();
return;
}
if (ButtonText == "M+")
{
// Memory add
MemoryStore += EndResult;
txtDisplay.Text = MemoryStore.ToString();
return;
}
Just change the variable MemoryStore to a global variable. At the moment, it is being re-declared each time a button is pushed, meaning that the data is lost between button presses. Move it outside of the function, and it should work fine.

Enums, clicking a button for x,y coordinates

I'm creating a Connect 4 game. However I'm stuck on clicking on the button and it will generate the x,y coordinates. Example: press button 1 - generates x:1 y:2 etc.
This is my code so far:
private void button1_Click(object sender, EventArgs e)
{
Output_textBox.AppendText("You have inserted in Column 1");
Output_textBox.AppendText(Environment.NewLine);
TextBox[] boxes = { textBox11, textBox12, textBox13, textBox14, textBox15, textBox16 };
if (currentState == Gamestate.Player1Turn)
{
if (boxes[counter].BackColor != SystemColors.HotTrack && boxes[counter].BackColor != Color.Red)
{
boxes[counter].BackColor = SystemColors.HotTrack;
return;
}
counter = counter + 1;
}
else if (currentState == Gamestate.Player2Turn)
{
if(boxes[counter].BackColor != SystemColors.HotTrack && boxes[counter].BackColor != Color.Red)
{
boxes[counter].BackColor = Color.Red;
// m_Connect4GameLogic.PlayerPlayed(player_enum, 1, 3);
return;
}
counter = counter + 1;
}
}
The comment bit is what someone advised me to write a similar code to it. However I don't really know how to use enums.
How do you use enums, and how would you the implement "click button1 (generates the x,y co-ordinates) and the button will pass information to the game logic "?

Calculation is wrong

What should happen
My exexcrise is it to prgramm a calculator which is able to do calculations in 'queue'.
Example:
User enters first number in txtZahl and then clicks one of the button. The needed calculation should be saved in the list numbers and txtZahl should be cleared. The user can now enter a new number and press a button etc.
When the user clicks on btnEqu the foreach should take every calculation from the list and do the calculation. If this is done the result should be displayed in txtZahl.
Problem
The calculations are not correct. For example I get 0.00 as result for 4-3.
I know that the idea with the extra class is not the best way, but I would like to keep it, to see what my teacher thinks about it.
Thank you for helping!
Code:
Form1.cs
double ergebniss = 0;
Boolean firstRun = true;
List<Rechnung> numbers = new List<Rechnung>();
Rechnung.RechenArt lastArt;
private void btnMinus_Click(object sender, EventArgs e)
{
if (isValid())
{
if (firstRun)
{
ergebniss = Convert.ToDouble(txtZahl.Text);
}
numbers.Add(new Rechnung(Convert.ToDouble(txtZahl.Text), Rechnung.RechenArt.Subtraktion));
lastArt = Rechnung.RechenArt.Subtraktion;
clearAndFocus();
}
}
private void btnEqu_Click(object sender, EventArgs e)
{
foreach (Rechnung r in numbers)
{
switch (r.getArt())
{
case Rechnung.RechenArt.Subtraktion:
{
ergebniss -= r.getNumber();
break;
}
}
}
txtZahl.Text = ergebniss.ToString("f2");
}
}
if (firstRun)
{
ergebniss = Convert.ToDouble(txtZahl.Text);
firstRun = false;
return;
}
first you forgot to
firstRun = false; after that
then I advice you to display just clean string
txtZahl.Text = ergebniss.ToString();
you also doesn't use lastArt variable don't know if that's necessary.

Categories