So the rest of the code is working fine but when it gets to the part where you have to select from predetermined values from the drop down menu, it doesn't display my options but instead allows the user to choose their own.
namespace A2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
comboBox1.Items.Add("15%");
comboBox1.Items.Add("18%");
comboBox1.Items.Add("20%");
}
private void button1_Click(object sender, EventArgs e)
{
double amount, tax, tip, total, final;
amount = double.Parse(textBox1.Text);
tax = amount * 0.1;
labelTax.Text = tax.ToString();
total = amount + tax;
labelTotal.Text = total.ToString();
tip = amount * double.Parse(comboBox1.Text);
labelTip.Text = tip.ToString();
final = amount + tip + tax;
labelFinal.Text = final.ToString();
}
}
}
The SelectedIndexChanged event is fired when the user changes a selection in the combo box. With your code above, any time they choose a new item, you're adding 3 more.
However, as it stands now, the combo box is empty when the form loads, so this event will never fire (there are no choices to select). And then, as you mention, the user can type something in themselves.
To fix this, you might want to move that code into the Form_Load event instead. This way, the combo box will have the items added from the start. You also might want to set the DropDownStyle to DropDownList, which will prevent the user from being able to type in the combo box. And then you can set the SelectedIndex to 0 so the first item is selected:
private void Form1_Load(object sender, EventArgs e)
{
comboBox1.Items.Add("15%");
comboBox1.Items.Add("18%");
comboBox1.Items.Add("20%");
comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
comboBox1.SelectedIndex = 0;
}
Another problem you will run into is having the percent sign as part of the comboBox item text. double.Parse() will not know what to do with this. In order to resolve this, you can use the string.Replace() method to replace the percent character with an empty string before parsing as a double.
Additionally, you will want to divide this whole number by 100 so it's treated as a percentage:
tip = amount * (double.Parse(comboBox1.Text.Replace("%", "")) / 100);
Another approach to use data-binding and have strong typed values.
Use decimal as type for money related calculations
public class Tax
{
public decimal Value { get; }
public string Text { get => Value.ToString("0.## '%'"); }
public Tax(decimal value)
{
Value = value;
}
}
private void Form1_Load(object sender, EventArgs e)
{
var taxes = new[]
{
new Tax(15),
new Tax(18),
new Tax(20),
}
comboBox1.ValueMember = "Value";
comboBox1.DisplayMember = "Text";
comboBox1.DataSource = taxes;
comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
comboBox1.SelectedValue = 15;
}
Then in button click you can access selected value
var selectedTax = (decimal)combobox.SelectedValue;
or you can get whole selected object
var selectedTax = (Tax)combobox.SelectedItem;
Related
I'm just starting off with C# and I've been stuck trying to understand what I'm doing wrong for a couple of hours. I've tried so many different variations with no success so I wouldn't be surprised if I'm completely off at this point. What I'm trying to do is suppose to allow the user to enter a value then click one radio button in each of the groups. So the user is expected to make a selection in the group 1 radio buttons first which will be the original type of measurement that is being entered into the textbox. Then select from the group 2 radio buttons what they would like to convert the value entered into the textbox to (for ex. in. to cm.) and after selecting 1 radio button from each group. Click the convert button which then should show the conversion in the output label.
Any guidance would be appreciated, thanks!
public partial class Form1 : Form
{
const double INCHEStoCM = 2.54;
const double INCHEStoM = 0.0254;
const double FEETtoCM = 30.48;
const double FEETtoM = 0.3048;
public Form1()
{
InitializeComponent();
}
private void buttonExit_Click(object sender, EventArgs e)
{
//to exit
{
DialogResult respExit;
respExit = MessageBox.Show("Would you like to exit?", "Distance Converter", MessageBoxButtons.YesNo);
if(respExit==DialogResult.Yes)
{
this.Close();
}
}
}
private void buttonReset_Click(object sender, EventArgs e)
{
textBoxNumber.Clear();
labelOutput.Text = "";
textBoxNumber.Focus();
}
private void buttonConvert_Click(object sender, EventArgs e)
{
double inNumber = 0, outMetricValue = 0;
try // check if data is a number
{
inNumber = double.Parse(Text);
outMetricValue = double.Parse(Text);
}
catch
{
MessageBox.Show("Data entered must be a number", "Distance Converter");
buttonReset.PerformClick();
return;
}
// check number is > 0; <0 is error
if(inNumber<0)
{
MessageBox.Show("Value entered must be >0", "Distance Converter App");
buttonReset.PerformClick();
return;
}
if (radioButtonInches.Checked && radioButtonCm.Checked)
{
outMetricValue = inNumber * INCHEStoCM;
labelOutput.Text = outMetricValue.ToString("n");
}
}
}
}
I have written a function AddItem that adds an item to a listview. I also have created a function to create dynamic buttons. But once i create a dynamic button i would like it to have the AddItem function work when the button is pressed.
I have no clue how i would solve this because im relatively new to C# and windows forms.
private void AddButton(string Name, string Text, int Posx, int Posy, double Price, string ItemName)
{
// Create a Button object
Button NewButton = new Button();
// Set Button properties
NewButton.Height = 50;
NewButton.Width = 120;
NewButton.BackColor = Color.Gainsboro;
NewButton.ForeColor = Color.Black;
NewButton.Location = new Point(Posx, Posy);
NewButton.Text = Text;
NewButton.Name = Name;
NewButton.Font = new Font("Microsoft Sans Serif", 12);
// Add a Button Click Event handler
NewButton.Click += new EventHandler(NewButton_Click);
//Add to form ontop of panelButtonHamburgers
panelButtonsHamburgers.Controls.Add(NewButton);
}
private void NewButton_Click(object sender, EventArgs e)
{
AddItem(Price, ItemName);
}
As you can see the AddButton function takes a price and itemname, once the button is clicked i would like the additem function to run with this same price and itemname.
Thanks!
As far as I understood, you need a hanlder that uses some specific values for each dynamic button. There are few approaches you can use.
Use Tag property and save values in some format
newBut.Tag = $"{Price},{ItemName}";
and than, in handler
//always check for null
Button button = sender as Button;
string data = button.Tag as string;
//do staff with your data
Create Dictionary and every time you add new button add it as a key to Dictionary and that, in handler get your data (but this is one of the worst way to do it, so try to avoid it);
Use "Command" pattern. Make a special class for executing your operation. It should look like this
class MyCommand
{
public double Price { get; set; }
public string Name { get; set; }
public ListView List { get; set; } //here is the list you want to add item to.
public void Handle (object sender, EventArgs e)
{
//Do your staff here
}
}
It is a little bit tricky but introduces good pattern you can use in future.
You could assign a tuple to the button's Tag.
private void AddButton(string Name, string Text, int Posx, int Posy, double Price, string ItemName)
{
...
NewButton.Tag = (Price, ItemName);
}
Then you can the get that tuple's values from the sender in the event, which actually is the button.
private void NewButton_Click(object sender, EventArgs e)
{
double price = (((double Price, string ItemName))((Button)sender).Tag).Price;
string itemName = (((double Price, string ItemName))((Button)sender).Tag).ItemName;
...
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I want to change dynamically TextBox values.
i did this but its not working.
private void txtPrice_TextChanged(object sender, EventArgs e)
{
Convert.ToString(Convert.ToInt16(txtRate.Text) * Convert.ToInt16(txtQty.Text));
}
Try this instead
private void txtPrice_TextChanged(object sender, EventArgs e)
{
int rate = 0;
int qty = 0;
Int32.TryParse(txtRate.Text, out rate);
Int32.TryParse(txtQty.Text, out qty);
int total = rate * qty
// Set the new textBox value
// txtTotal should be your textbox value (what you have called it)
txtTotal.Text = total.toString()
}
I´m not a native C# developer so there might be some adjustments in the syntax.
As dotctor inferred, you're performing an operation but leaving it lost in space. You need to do something like this:
String valToChange;
private void txtPrice_TextChanged(object sender, EventArgs e)
{
valToChange = Convert.ToString(Convert.ToInt16(txtRate.Text) * Convert.ToInt16(txtQty.Text));
}
It's not clear which textbox value you want to change, though: you're using the changed event of txtPrice, so if you change that like this:
private void txtPrice_TextChanged(object sender, EventArgs e)
{
txtPrice.Text = Convert.ToString(Convert.ToInt16(txtRate.Text) * Convert.ToInt16(txtQty.Text));
}
...you will have a problem with the same event being called when you change that value. That's why I just put a "valToChange" there. You will have to adjust as needed.
You should assign a handler for TextChanged event of both txtQty and txtRate;
private void txtQty_TextChanged(object sender, EventArgs e)
{
UpdatePrice();
}
private void txtRate_TextChanged(object sender, EventArgs e)
{
UpdatePrice();
}
//code from user2893289 answer
private void UpdatePrice()
{
int r = 0, q = 0;
int.TryParse(txtRate.Text, out r);
int.TryParse(txtQty.Text, out q);
txtPrice.Text = (r*q).toString()
}
You should favor using int.TryParse over Convert.ToInt32 because Convert.ToInt32 will throw exception if input string format is not correct.
This works for me:
double rate = Convert.ToDouble(txtRate.Text);
int qty = Convert.ToInt32(txtQty.Text);
txtPrice.Text = ((double)rate*qty).ToString();
It assumes that txtRate contains a value such as "3.00" and that txtQty contains a value such as "7"
UPDATE
Since the rate is "readonly" this might be a better way to do it:
const double RANA_RASHIDS_RATE = 3.14; // or whatever it should be
. . .
txtRate.Text = RANA_RASHIDS_RATE.ToString(); // this is just for show
double rate = RANA_RASHIDS_RATE;
int qty = Convert.ToInt32(txtQty.Text);
txtPrice.Text = ((double)rate*qty).ToString();
UPDATE 2
Make sure there's a value in txtQty, or use a fake value (1):
const double RANA_RASHIDS_RATE = 3.14; // or whatever it should be
. . .
txtRate.Text = RANA_RASHIDS_RATE.ToString(); // this is just for show
double rate = RANA_RASHIDS_RATE;
int qty = 1;
if (!txtQty.Text.Trim().Equals(String.Empty))
{
qty = Convert.ToInt32(txtQty.Text);
}
txtPrice.Text = ((double)rate*qty).ToString();
There are other things you could do, if you want to get "fancy," such as monitor the change event of txtQty and only allow numerical values and backspace to be entered. That is left as an exercise for the questioner, though.
I'm relatively new to programming; I know the basics of C and even less in C#. I'm trying to write a program for my job that will allow the user to enter a value, this value will increase or decreased a contract amount. I've looked everywhere and can't find the exact answer I need. I tried a for loop until I read that a Windows Form is a loop.
The issue I'm having is every time a user enters a second value the program calculates the amount from the original contract value, it's not keeping the updated value after the calculation. If I was writing this as a console app I could figure out but I don't have a lot of experience with Forms.
here is my code for the Button_Click:
private void button1_Click(object sender, EventArgs e)
{
const double CONTRACT_BALANCE = 229481.65;
const double SUB_BALANCE = 196817.63;
double subBal = SUB_BALANCE;
double bal = CONTRACT_BALANCE;
double enterPayment = 0;
subBalLabel.Text = subBal.ToString("C");
balanceLabel.Text = bal.ToString("C");
//User Input Payment
enterPayment = Double.Parse(payCOTextBox.Text);
// balances
subBal = subBal + enterPayment;
bal = bal + enterPayment;
// Text Labels
subBalLabel.Text = subBal.ToString("C");
balanceLabel.Text = bal.ToString("C");
// Update Balance Label
subBalLabel.Update();
balanceLabel.Update();
// Clear Text Box
payCOTextBox.Clear();
Your subbal and bal variables are local to the method, which means they don't hold their values across calls. Move them out to Class/Form level so they can be used over time:
public partial class Form1 : Form
{
const double CONTRACT_BALANCE = 229481.65;
const double SUB_BALANCE = 196817.63;
double subBal = SUB_BALANCE;
double bal = CONTRACT_BALANCE;
public Form1()
{
InitializeComponent();
this.Load += Form1_Load;
}
void Form1_Load(object sender, EventArgs e)
{
subBalLabel.Text = subBal.ToString("C");
balanceLabel.Text = bal.ToString("C");
}
private void button1_Click(object sender, EventArgs e)
{
double enterPayment = 0;
subBalLabel.Text = subBal.ToString("C");
balanceLabel.Text = bal.ToString("C");
//User Input Payment
enterPayment = Double.Parse(payCOTextBox.Text);
// balances
subBal = subBal + enterPayment;
bal = bal + enterPayment;
// Text Labels
subBalLabel.Text = subBal.ToString("C");
balanceLabel.Text = bal.ToString("C");
// Clear Text Box
payCOTextBox.Clear();
}
}
I've created a Sudoku Game and I have 23 Digits that are covered for the user and that he needs too solve.
I'm wondering if it's possible that through a Label show the user how many textboxes that are left over without an digit in them.
I've created the game through WinForms and I've pretty much come to an hold. If anyone can throw me in the right direction it would be much appreciated!
I created the textboxes and used arrays, then I randomized a finished sudoku. The randomizer is a whole class for itself and after that I pretty much assigned arrays
private void assign_Char_Value(string[] s_Rem_Value)
{
arr_Char_Value = (s_Rem_Value[0] + s_Rem_Value[1] + s_Rem_Value[2]
+ s_Rem_Value[3] + s_Rem_Value[4] + s_Rem_Value[5] + s_Rem_Value[6]
+ s_Rem_Value[7] + s_Rem_Value[8]).ToCharArray();
int i_Cnt = 0;
foreach (TextBox[] arr_txtBox in validate.arr_txtBox_Horiz)
{
foreach (TextBox txtBox in arr_txtBox)
{
txtBox.Text = arr_Char_Value[i_Cnt].ToString();
i_Cnt++;
}
}
Rondomize_Numbers();
}
After that I chose int number = 23;
I have 3 buttons one of them correct the game another randomizes a new game and the other shows the rules of sudoku.
Let's assume for simplicity you have all your textboxes in a panel.
and that the textboxes are the only items in the panel.
Now have your textboxes hookup to the same textBox_TextChanged event like this:
public Form1()
{
InitializeComponent();
foreach (TextBox txtBox in panel1.Controls)
{
txtBox.TextChanged += textBox_TextChanged;
}
}
now for the event:
private void textBox_TextChanged(object sender, EventArgs e)
{
var emptyCounter = 0;
foreach (TextBox txtBox in panel1.Controls)
{
if (String.IsNullOrWhiteSpace(txtBox.Text))
{
emptyCounter++;
}
}
label1.Text = emptyCounter.ToString();
}
you could also use a LINQ statement instead of the foreach above making the method look like this:
private void textBox_TextChanged(object sender, EventArgs e)
{
var emptyCounter = panel1.Controls.OfType<TextBox>().Count(txtBox => String.IsNullOrWhiteSpace(txtBox.Text));
label1.Text = emptyCounter.ToString();
}
Hope this helps.