Output to textbox and improving the code - c#

So I'm learning C# and just hit the Forms section and it's not going aswell as I hoped and Im feeling as my code isn't properly written.
Im also having problems figuring out how to output my calculated varible Im writting in with a button press.
What im asking for : Help with outputing my calculation from CalcFuelConsumptionPerKm() for example too a uneditible textbox by pressing a button
Also thanks for editing and helping out a beginner like me! You guys are awesome!
http://i.imgur.com/fcvV0yH.png > how Winform looks
Winform :
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
double obedomitor, fuel, price , oldvalue;
Fuel fc;
public Form1()
{
InitializeComponent();
fc = new Fuel();
}
private void GroupBox1_Enter(object sender, EventArgs e)
{
}
private void TextBox1_TextChanged(object sender, EventArgs e)
{
if (TextBox1.Text.Trim() != "")
{
try
{
obedomitor = Convert.ToDouble(TextBox1.Text.Trim());
fc.SetCurrentReading(obedomitor);
}
catch
{
MessageBox.Show("Please enter a valid number");
TextBox1.Text = "";
}
}
}
private void TextBox2_TextChanged(object sender, EventArgs e)
{
if (TextBox2.Text.Trim() != "")
{
try
{
oldvalue = Convert.ToDouble(TextBox1.Text.Trim());
fc.setPreviousReading(oldvalue);
}
catch
{
MessageBox.Show("Please enter a valid number");
TextBox2.Text = "";
}
}
}
private void Button1_Click(object sender, EventArgs e)
{
}
private void TextBox3_TextChanged(object sender, EventArgs e)
{
if (TextBox3.Text.Trim() != "")
{
try
{
fuel = Convert.ToDouble(TextBox3.Text.Trim());
fc.SetFuelAmount(fuel);
}
catch
{
MessageBox.Show("Please enter a valid number");
TextBox1.Text = "";
}
}
}
private void TextBox4_TextChanged(object sender, EventArgs e)
{
if (TextBox4.Text.Trim() != "")
{
try
{
price = Convert.ToDouble(TextBox4.Text.Trim());
fc.setUnitPrice(price);
}
catch
{
MessageBox.Show("Please enter a valid number");
TextBox1.Text = "";
}
}
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void TextBox5_TextChanged(object sender, EventArgs e)
{
}
private void TextBox7_TextChanged(object sender, EventArgs e)
{
}
}
}
My other class :
namespace WindowsFormsApplication1
{
class Fuel
{
double CurrentCal;
double FuelAmount;
double PreReading;
double unitPrice;
double km;
public void Fuelcalculator()
{
GetPreviousReading();
}
public double CalcConsumptionKilometerPerLiter()
{
km = CurrentCal - PreReading;
double litPerKm = FuelAmount / km;
return litPerKm;
}
public double CalcConsumptionPerMetricMile()
{
const double kmToMileFactor = 0.621371192;
double litPerKm = CalcConsumptionKilometerPerLiter();
double litPerMetricMile = litPerKm / kmToMileFactor;
return litPerMetricMile;
}
public double CalcCostPerKm()
{
double cost = (FuelAmount / km) * unitPrice;
return cost;
}
public double CalcFuelConsumptionPerKm()
{
double consumption = FuelAmount / km;
return consumption;
}
public double CalcConsumptionKilometerPerSweMil()
{
double literPerMil = CalcConsumptionKilometerPerLiter();
literPerMil = literPerMil*10;
return literPerMil;
}
public double GetCurrentReading()
{
return CurrentCal;
}
public double GetFuelAmount()
{
return FuelAmount;
}
public double GetPreviousReading()
{
double previous = CurrentCal;
return previous;
}
public double UnitPrice()
{
return unitPrice;
}
public void SetCurrentReading(double newValue)
{
CurrentCal = newValue;
}
public void SetFuelAmount(double newValue)
{
FuelAmount = newValue;
}
public void setPreviousReading(double newValue)
{
PreReading = newValue;
}
public void setUnitPrice(double newValue)
{
unitPrice = newValue;
}
}
}

If you want everything to update in realtime (which it sounds like you do) I would have a "UpdateResult" method that sets all the "output" text box's text properties:
private void UpdateResult()
{
TextBox3.Text = fc.CalcConsumptionKilometerPerLiter().ToString();
//All the others
}
And invoke that once you have validated the user's input in the "TextChanged" events. For example:
private void TextBox1_TextChanged(object sender, EventArgs e)
{
if (TextBox1.Text.Trim() != "")
{
try
{
obedomitor = Convert.ToDouble(TextBox1.Text.Trim());
fc.SetCurrentReading(obedomitor);
UpdateResults();
}
catch
{
MessageBox.Show("Please enter a valid number");
TextBox1.Text = "";
}
}
}
A couple quick notes since you are learning:
TextBoxX is not a good naming convention. Give your controls descriptive names
Since you mentioned it in a comment, double.TryParse is used for converting inputted strings into numbers. It shouldn't be involved in your output
Instead of using .Trim != "", you could just use !String.IsWhitespaceOrEmpty. It reads a lot better :)
If you expect user error, exceptions are expensive. Use double.TryParse instead of Convert.ToDouble (which really uses double.Parse) so you can have a safer, non-throwing check for user input.

Related

7 Day Average Cases Form

I am a newbie and I am honestly struggling a lot with this. I am trying to calculate all the entries from the texbox to the listbox and then divide by 7 and display the average in an output label. I am having trouble displaying the case average. Here is the code:
public partial class formAverageWeeklyCases : Form
{
int SEVEN = 7;
public formAverageWeeklyCases()
{
InitializeComponent();
}
private void buttonExit_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void buttonEnter_Click(object sender, EventArgs e)
{
if (textBoxCaseEntry.Text.Trim().Length >= 1)
{
listBoxDailyCases.Items.Add(textBoxCaseEntry.Text.Trim());
textBoxCaseEntry.Text = string.Empty;
textBoxCaseEntry.Focus();
}
else
{
MessageBox.Show("The number entered does not appear to be valid");
textBoxCaseEntry.Text = string.Empty;
textBoxCaseEntry.Focus();
}
}
private void buttonReset_Click(object sender, EventArgs e)
{
textBoxCaseEntry.Text = string.Empty;
listBoxDailyCases.Items.Clear();
labelOutputDailyAverage.Text = string.Empty;
}
private void textBoxAverageWeeklyCases_TextChanged(object sender, EventArgs e)
{
if (listBoxDailyCases.SelectedItems.Count <= SEVEN)
{
double average = listBoxDailyCases.SelectedItems.Count / SEVEN;
labelOutputDailyAverage.Text.Show(+average);
}
else
{
MessageBox.Show("Please enter a only 7 case count numbers");
}
}
}
If I understand you correctly, you want to collect 7 numbers from the user and then calculate the average? If yes, I suggest you declare a list of ints (or doubles if you need doubles), then call TryParse to validate the user input and then calculate the average when needed:
public partial class formAverageWeeklyCases : Form
{
const int SEVEN = 7;
private List<int> numbers = new List<int>(SEVEN); // NEW
public formAverageWeeklyCases()
{
InitializeComponent();
}
private void buttonExit_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void buttonEnter_Click(object sender, EventArgs e)
{
if (int.TryParse(textBoxCaseEntry.Text.Trim(), out int parsed)) // NEW
{
numbers.Add(parsed); // NEW
textBoxCaseEntry.Text = string.Empty;
textBoxCaseEntry.Focus();
}
else
{
MessageBox.Show("The number entered does not appear to be valid");
textBoxCaseEntry.Text = string.Empty;
textBoxCaseEntry.Focus();
}
}
private void buttonReset_Click(object sender, EventArgs e)
{
textBoxCaseEntry.Text = string.Empty;
listBoxDailyCases.Items.Clear();
labelOutputDailyAverage.Text = string.Empty;
}
private void textBoxAverageWeeklyCases_TextChanged(object sender, EventArgs e)
{
if (listBoxDailyCases.SelectedItems.Count <= SEVEN)
{
double average = numbers.Sum() / SEVEN; // NEW
labelOutputDailyAverage.Text = average.ToString();
}
else
{
MessageBox.Show("Please enter a only 7 case count numbers");
}
}
}

Quick simple example for learning delegate event

I'm a new beginner on this topic. I created a c# win form. In this form, I have two textboxes and one label. What I want to do is create a delegate event to track the textbox's change and add up two numbers from textbox1 and textbox2. The label will show the result automatically. Hope someone can provide me a example for this, thank you so much! There is something I have right now,
events.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Project3
{
public delegate void Calculate(int obj1, int obj2);
public class events
{
int result;
public int Add(int x, int y)
{
result = x + y;
return result;
}
}
}
Form1.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Project3
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
label1.Text ="";
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
}
}
}
If you just want to learn how to delegate the result into the label, and learn the delegate and event, here is a sample you may want to try and analyze for learning purposes:
Sample 1:
public delegate int CalculateEventHandler(object obj1, object obj2);
public partial class Form1 : Form
{
public event CalculateEventHandler Calculate;
private string OnCalculate(string text1, string text2)
{
string result = "0";
if (this.Calculate != null)
{
result = this.Calculate(this.textBox1.Text, this.textBox2.Text).ToString();
}
return result;
}
public Form1()
{
this.InitializeComponent();
this.InitializeEvent();
}
private void InitializeEvent()
{
this.Calculate += Form1_Calculate;
}
private int Form1_Calculate(object obj1, object obj2)
{
int a = 0;
int b = 0;
int.TryParse(obj1.ToString(), out a);
int.TryParse(obj2.ToString(), out b);
return a + b;
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
this.label1.Text = OnCalculate(this.textBox1.Text, this.textBox2.Text);
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
this.label1.Text = OnCalculate(this.textBox1.Text, this.textBox2.Text);
}
}
Sample 2:
Form1.cs
public partial class Form1 : Form
{
public Form1()
{
this.InitializeComponent();
this.InitializeEvent();
}
private void InitializeEvent()
{
Event.Calculate += Event_Calculate;
}
private int Event_Calculate(object obj1, object obj2)
{
int x = 0;
int y = 0;
int.TryParse(obj1.ToString(), out x);
int.TryParse(obj2.ToString(), out y);
return Event.Add( x, y );
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
this.label1.Text = Event.OnCalculate(this.textBox1.Text, this.textBox2.Text).ToString();
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
this.label1.Text = Event.OnCalculate(this.textBox1.Text, this.textBox2.Text).ToString();
}
}
Event.cs
public delegate int CalculateEventHandler(object obj1, object obj2);
public class Event
{
static public event CalculateEventHandler Calculate;
static public int Add(int x, int y)
{
int result = x + y;
return result;
}
static public int OnCalculate( object obj1, object obj2 )
{
int result = 0;
if( Calculate != null )
{
result = Calculate(obj1, obj2);
}
return result;
}
}
NOTE: The above examples are by no means a good approach to calculate two values, this just serves as an example. The disadvantage of this approach would lead you to somehow spaghetti code, going back and forth to where the logic is going.
There is a simple solution
private void textBox1_TextChanged(object sender, EventArgs e)
{
try
{
if (textBox2.Text == string.Empty)
{
//textBox2.Text = (0).ToString();
label1.Text = ( Convert.ToInt32(textBox1.Text)).ToString();
}
else if (textBox1.Text == string.Empty)
{
label1.Text = (Convert.ToInt32(textBox2.Text)).ToString();
}
else
{
label1.Text = (Convert.ToInt32(textBox1.Text) + Convert.ToInt32(textBox2.Text)).ToString();
}
}
catch (Exception e3)
{
MessageBox.Show(e3.Message);
}
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
try
{
if (textBox2.Text == string.Empty)
{
//textBox2.Text = (0).ToString();
label1.Text = (Convert.ToInt32(textBox1.Text)).ToString();
}
else if (textBox1.Text == string.Empty)
{
label1.Text = (Convert.ToInt32(textBox2.Text)).ToString();
}
else
{
label1.Text = (Convert.ToInt32(textBox1.Text) + Convert.ToInt32(textBox2.Text)).ToString();
}
}
catch (Exception e3)
{
MessageBox.Show(e3.Message);
}
}

How to get value from one form to an other?

I made a form for deleting/removing products.
Now my question is how do I get the value from one form to the other so I can use this to update the amount of products or delete the products from a database?
I'm trying to get the value of tbAantal.Text, so I can use this in my other form to update the amount of products.
Or should I do it in a other way?
public partial class Bevestiging : Form
{
public Bevestiging()
{
InitializeComponent();
Aantal = 0;
}
public int Aantal { get; set; }
private void btnOk_Click(object sender, EventArgs e)
{
int aantal;
if (!int.TryParse(tbAantal.Text, out aantal))
{
MessageBox.Show("U kunt alleen numerieke waardes invullen.", "Fout");
return;
}
}
private void btnCancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
private void BtUp_Click(object sender, EventArgs e)
{
Aantal++;
tbAantal.Text = Aantal.ToString();
}
private void BtDown_Click(object sender, EventArgs e)
{
Aantal--;
tbAantal.Text = Aantal.ToString();
}
So I can use this to update it here:
private void gridGeregistreerd_ColumnButtonClick(object sender, ColumnActionEventArgs e)
{
var dialog = new Bevestiging();
if (DialogResult.OK != dialog.ShowDialog()) ;
}
You've already made the public property "Aantal" on your first form with the right get/set so to retrieve the value on your second form use this:
using (Bevestiging myForm = new Bevestiging())
{
DialogResult result = myForm.ShowDialog();
if (result != DialogResult.OK)
{
int returnedValue = myForm.Aantal;
}
}
In you form, you have already define a public property :
public partial class Bevestiging : Form
{
public int Aantal {
get; set;
}
}
Then in your callee form, you can access it :
private void gridGeregistreerd_ColumnButtonClick(object sender, ColumnActionEventArgs e)
{
var dialog = new Bevestiging();
if (DialogResult.OK != dialog.ShowDialog())
{
int aantal = dialog.Aantal;
/* Save it to database or whatever you want */
}
}

How to use class type array in different forms in c#

I am beginner to c#. I am stuck on this assignment. I am trying to store values in class type global array but array is not saving this. I have tried a lot but failed.
Here is the code:
public class GlobalVariable
{
public static Employeeclass[] staff = new Employeeclass[10];
public static int total=0;
}
public class Employeeclass
{
public int id;
public string name;
public double salary;
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
var myform = new Form2();
myform.Show();
}
private void button2_Click(object sender, EventArgs e)
{
var myForm = new Form3();
myForm.Show();
}
private void button3_Click(object sender, EventArgs e)
{
double totalsalary = 0;
for (int i = 0; i < GlobalVariable.total; i++)
{
totalsalary+=GlobalVariable.staff[i].salary;
}
string a = GlobalVariable.total.ToString();
string b = totalsalary.ToString();
MessageBox.Show("total employee = " + a +"\ntotal salary = " + b);
}
}
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
void textBox2_KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = !(char.IsLetter(e.KeyChar) || e.KeyChar == (char)Keys.Back);
}
public void button1_Click(object sender, EventArgs e)
{
if (textBox2 == null)
{
MessageBox.Show("please enter employee name");
}
else
{
GlobalVariable.staff[GlobalVariable.total].id = Convert.ToInt32(textBox1.Text);
GlobalVariable.staff[GlobalVariable.total].name = textBox2.Text;
GlobalVariable.staff[GlobalVariable.total].salary = 0.0;
GlobalVariable.total++;
}
this.Close();
}
private void Form2_Load(object sender, EventArgs e)
{
textBox1.Text = (GlobalVariable.total + 1).ToString();
}
}
public partial class Form3 : Form
{
//string temp;
//double a;
public Form3()
{
InitializeComponent();
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
comboBox1.Items.Clear();
for (int i = 0; i < GlobalVariable.total; i++)
{
comboBox1.Items.Insert(i,GlobalVariable.name[i]);
// comboBox1.Items.Add(GlobalVariable.name[i]);
}
if (comboBox1.SelectedItem != null)
{
textBox1.Enabled = true;
}
}
private void button2_Click(object sender, EventArgs e)
{
var myform = new Form2();
myform.Show();
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
if (comboBox1.SelectedItem != null)
{
textBox1.Enabled = true;
}
}
}
Your code doesn't initialize the employees. You have to create a new instance of the employee first (unlike with structs, where the default is already a fully working "instance"):
public void button1_Click(object sender, EventArgs e)
{
if (textBox2 == null)
{
MessageBox.Show("please enter employee name");
}
else
{
// Create a new instance in the array
GlobalVariable.staff[GlobalVariable.total] = new Employeeclass();
GlobalVariable.staff[GlobalVariable.total].id =
Convert.ToInt32(textBox1.Text);
GlobalVariable.staff[GlobalVariable.total].name = textBox2.Text;
GlobalVariable.staff[GlobalVariable.total].salary = 0.0;
GlobalVariable.total++;
}
this.Close();
}
However, I have to point out this is a very unhappy design. Global variables? Fixed-length arrays for variable-length data? Non-existent encapsulation?
For example, a better way might be to create the dialogs as, well, dialogs:
private NewEmployeeForm()
{
InitializeComponent();
}
public static EmployeeClass ShowDialog()
{
var frm = new NewEmployeeForm();
while (frm.ShowDialog() == DialogResult.OK)
{
if (string.IsNullOrEmpty(frm.tbxName.Text))
{
MessageBox.Show("Please, enter the employee name.");
}
else
{
var emp = new EmployeeClass();
emp.Id = int.Parse(frm.tbxId.Text);
emp.Name = frm.tbxName.Text);
return emp;
}
}
return null;
}
Forget coding like it's 1980. It's really necessary to separate your code into more or less isolated parts. Read up a bit on object oriented programming, especially encapsulation. Use meaningful names for your variables and controls, even in your learning projects! You really need the habit, it's non-negotiable.
Also, try to look for a way that solves your problem first. For example, there's a List class in .NET, that handles a self-expanding list of data. So you can use something like this:
List<EmployeeClass> employees = new List<EmployeeClass>();
employees.Add(emp1);
employees.Add(emp2);
employees.Add(emp3);
MessageBox.Show("I've got " + employees.Count + " employees!");
Don't forget error handling. I know you're just making a learning project, but again, you want the right habits. Parsing a string to an integer? Check that it's actually an integer first. Handle the possible exception. Use data validation. If I enter hi in your textBox1, your application is going to crash or show an "break / continue / abort" dialogue. That's not good.
You need to initialize each of the "EmployeeClass" Objects in your array.
By default, when the array is created it has 10 slots filled with "null"
I recommend adding a static constructor:
public static class GlobalVariable
{
public static Employeeclass[] staff;
public static int total=0;
static GlobalVariable()
{
staff = new Employeeclass[10];
for (int i = 0; i < staff.Length; i++)
staff[i] = new EmployeeClass();
}
}
The static constructor is called when you first reference anything in the GlobalVariable class. Also the class should be declared "static" because all of its members are static. The compiler can make more efficient code in this way.
Cheers and good luck learning C#
for (int i = 0; i < GlobalVariable.total; i++)
GlobalVariable.total is 0, so this loop will never be run through. Either set total to 10, or change to:
for (int i = 0; i < GlobalVariable.staff.Count; i++)
Also, there's no actual elements in the staff array, so it wouldn't work anyway.

Having problems removing a string from a sting list

I want to remove an item from a list...
I am obviously missing something...I have tried just about every variation including EXCEPT, REMOVE, etc...
When debugging, I step through each ling, but when it gets to btnRemove_Click, it steps through removing but does not remove anything...it acts as if I never sent a command to remove anything???
Help!
public partial class frmUpdate : Form
{
private Student student = new Student();
private string _scores;
public frmUpdate()
{
InitializeComponent();
}
public string GetUpdatedScores(Student s)
{
txtName.Text = s.Name;
_scores = s.Scores;
FillStudentGrades();
this.ShowDialog();
return _scores;
}
private void FillStudentGrades()
{
lstScores.Items.Clear();
string[] grades = splitGrades(_scores);
foreach (string s in grades)
{
lstScores.Items.Add(s.ToString());
}
}
private void lstScores_SelectedIndexChanged(object sender, EventArgs e)
{
int i = lstScores.SelectedIndex;
}
private void btnAdd_Click(object sender, EventArgs e)
{
frmAddScore addScore = new frmAddScore();
_scores += " " + addScore.AddScore();
FillStudentGrades();
}
private void btnUpdate_Click(object sender, EventArgs e)
{
int i = lstScores.SelectedIndex;
}
private void btnRemove_Click(object sender, EventArgs e)
{
int i = lstScores.SelectedIndex;
}
private void btnRemove_Click(object sender, EventArgs e)
{
if (lstScores.SelectedIndex < 0)
{
MessageBox.Show("You Must Select A Grade.");
btnUpdate.Focus();
}
else
{
int i = lstScores.SelectedIndex;
string[] grades = splitGrades(_scores);
string message = "Are you sure you want to remove " + grades[i].ToString() + "?";
DialogResult button = MessageBox.Show(message, "Confirm Remove",
MessageBoxButtons.YesNo);
if (button == DialogResult.Yes)
{
int count = 0;
foreach (char c in grades[i])
{
if (char.IsDigit(c))
{
count++;
}
}
int a = _scores.IndexOf(grades[i].ToString());
_scores = _scores.Remove(a, (count + 1));
FillStudentGrades();
btnOk.Focus();
}
else
{
btnOk.Focus();
}
}
}
private void btnClearAll_Click(object sender, EventArgs e)
{
}
private void btnOk_Click(object sender, EventArgs e)
{
student.Name = txtName.Text;
student.Scores = _scores;
this.Close();
}
private void btnExit_Click(object sender, EventArgs e)
{
this.Close();
}
public string[] splitGrades(string s)
{
string[] grades = s.Split(' ');
return grades;
}
}
In C#, strings are immutable. _scores.Remove(i); doesn't change _scores. Instead it returns a new string object that you can assign to a variable, for example, back to _scores like this:
_scores = _scores.Remove(i);
you need to use RemoveAt methos - as you are trying to remove index and not the value

Categories

Resources