Overloading methods in WPF C# - c#

Hi there I'am quite new to c# and WPF and was wondering if anyone could help me with a problem that I am currently having. I am trying to overload 3 methods in a very simple and basic wpf app (just to see how/if it works) but at run time when I try to check option one or two the application reports and error and closes. However If I check option 3 the application runs as intended. Any one that has any hints tips or solutions would be great. (Here is a code snippet of my basic app).
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void calculate_Click(object sender, RoutedEventArgs e)
{
int val = int.Parse(first.Text);
int val1 = int.Parse(second.Text);
int val2 = int.Parse(third.Text);
if ((bool)oneValue.IsChecked)
showTotal(val);
else if ((bool)twoValues.IsChecked)
showTotal(val, val1);
else if ((bool)threeValues.IsChecked)
showTotal(val, val1, val2);
}
private void showTotal(int val, int val1, int val2)
{
val = int.Parse(first.Text);
val1 = int.Parse(second.Text);
val2 = int.Parse(third.Text);
int total = val + val1 + val2;
result.Text = total.ToString();
}
private void showTotal(int val, int val1)
{
val = int.Parse(first.Text);
val1 = int.Parse(second.Text);
int total = val + val1;
result.Text = total.ToString();
}
private void showTotal(int val)
{
val = int.Parse(first.Text);
result.Text = val.ToString();
}
private void quit_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
}

Your overloads look correct to me. You probably don't have anything in your second or thrid text box if the second or third checkbox is not checked (it's hard to tell without more details). So the first thing you are doing is parsing all three text boxes, but if it's empty then you will get an exception. You can use TryParse which attempts to parse the string, but if it can not just returns false and you can gracefully handle it.
What I would do is something like this:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void calculate_Click(object sender, RoutedEventArgs e)
{
int val, val1, val2;
if (!int.TryParse(first.Text, out val))
{
val=0; // Invalid or blank input get's a zero (or you could show an error message)
}
if (!int.TryParse(second.Text, out val1))
{
val1=0; // Invalid or blank input get's a zero (or you could show an error message)
}
if (!int.TryParse(third.Text, out val2))
{
val2=0; // Invalid or blank input get's a zero (or you could show an error message)
}
if ((bool)oneValue.IsChecked)
showTotal(val);
else if ((bool)twoValues.IsChecked)
showTotal(val, val1);
else if ((bool)threeValues.IsChecked)
showTotal(val, val1, val2);
}
private void showTotal(int val, int val1, int val2)
{
int total = val + val1 + val2;
result.Text = total.ToString();
}
private void showTotal(int val, int val1)
{
int total = val + val1;
result.Text = total.ToString();
}
private void showTotal(int val)
{
result.Text = val.ToString();
}
private void quit_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
}

I see two things wrong with this code. The first is that I'm going to guess that you're having input validation in that the text can't be parsed into an integer. As a best practice, use int.TryParse, i.e.
int val;
if (!int.TryParse(first.Text, out val))
{
// Handle error
}
The second issue is that you're basically overwriting any parameters you're passing in. Why not just either have different methods for the # of inputs, or take a single parameter that indicates how many inputs you should use.
In fact, I'm not sure that overloading here is the correct approach. Why not use params:
private void showTotal(params string[] inputs)
{
int total = 0;
foreach (string input in inputs)
{
int val;
if (int.TryParse(input, out val))
total += total;
}
result.Text = total.ToString();
}
You can call it like
if ((bool)oneValue.IsChecked)
showTotal(first.Text);
else if ((bool)twoValues.IsChecked)
showTotal(first.Text, second.Text);
else if ((bool)threeValues.IsChecked)
showTotal(first.Text, second.Text, third.Text);

1) You are trying to parse your values twice
2) here Your bool cast is redundant because IsChecked already bool
if ((bool)oneValue.IsChecked)
3) Instead of parse, use TryParse it won't throw exception
int val, val1, val2;
if (oneValue.IsChecked)
{
if (int.TryParse(first.Text, val))
{
showTotal(val);
}
}
else if (twoValues.IsChecked)
{
if (int.TryParse(second.Text, val1))
{
showTotal(val, val1);
}
}
else if (threeValues.IsChecked)
{
if (int.TryParse(third.Text, val2)
{
showTotal(val, val1, val2);
}
}
4) Also you can use params keyword instead of method overloading.I guess it is more suitable in your case.With params keyword you can do your job with one method like this:
private void showTotal(params int[] numbers)
{
if(numbers != null)
{
int sum = numbers.Sum();
result.Text = sum.ToString();
}
}

Are you sure that the value of first.Text, second.Text, and third.Text are integer values? Calling int.Parse() on a non-integer value will throw an error. You might want to look into using int.TryParse() instead:
private void showTotal(int val)
{
bool gotResult = int.TryParse(first.Text, out val);
if(gotResult)
result.Text = val.ToString();
}
Furthermore, I'm pretty sure you application is failing on the "one" and "two" scenarios because this code:
private void calculate_Click(object sender, RoutedEventArgs e)
{
int val = int.Parse(first.Text);
int val1 = int.Parse(second.Text);
int val2 = int.Parse(third.Text);
Will fail unless first, second, and third all contain values. If second or third contains null or an empty string, you will get an error from int.Parse.

Related

How to solve textbox text changed event..?

private void rateTextBox_TextChanged(object sender, EventArgs e)
{
if (String.IsNullOrEmpty(pieceTextBox.Text))
{
}
else if (string.IsNullOrEmpty(rateReturnTextBox.Text))
{
}
else
{
int piece = Convert.ToInt32(pieceTextBox.Text);
int rate = Convert.ToInt32(rateTextBox.Text);
int netTotal = piece * rate;
netTotalBillTextBox.Text = netTotal.ToString();
}
}
//why dose not show the multiplication answer....where is the mistake?
I want this answer in netTotalBillTextBox .
Apparently, in the second condition shouldn't compare rateTextBox?
I assume it will always return string.Empty in rateReturnTextBox.

Pass += or -= as a parameter in c#

I have a method from a button click with the following code in c# (small golf scoring program I'm working on just for fun):
private void btnPlus_Click(object sender, EventArgs e)
{
btnMinus.Enabled = true;
if (f_intHoleNumber != 18) { f_intHoleNumber += 1; }
if (f_intHoleNumber == 18) { btnPlus.Enabled = false; }
txtHoleNumber.Text = f_intHoleNumber.ToString();
}
I would like to refactor that and extract another method from it so I don't reuse code but i'm not sure if its possible to pass an operator (+=) as a parameter to a method. Can this be done?
I don't think so. What about passing +1 or -1 to the method and multiplying it with the value to add or to subtract.
For example:
public float calc(float val1, float val2, int op)
{
return val1 + op * val2;
}
You can pass a method that does the adding and subtracting for you. You probably want to go that route.
Pass Method as Parameter using C#
You could pass a Func<int, int> which accepts one int parameter and returns an int.
private void btnPlus_Click(object sender, EventArgs e)
{
HandleHoleChange(currentHole => currentHole + 1);
}
private void HandleHoleChange(Func<int, int> getNextHoleFunc)
{
btnMinus.Enabled = true;
if (f_intHoleNumber != 18) { f_intHoleNumber = getNextHoleFunc(f_intHoldNumber); }
if (f_intHoleNumber == 18) { btnPlus.Enabled = false; }
txtHoleNumber.Text = f_intHoleNumber.ToString();
}
the accepted answer allows to pass a 0 which would mess up the calculation. If you want only to allow for addition or subtraction you can use a boolean variable to specify it in the parameterlist:
public float calc(float val1, float val2, bool add)
{
int op = add ? 1 : -1;
return val1 + op * val2;
}

Combobox value (binded with an enum) in an instance

Good day lads!
I've got a question.
I think I'll be saving loads of text if you would see my form, so here we go!
Form:
private void Form1_Load(object sender, EventArgs e)
{
/*
Held h1 = new Held("Tank", Lanes.Top);
Held h2 = new Held("ADC", Lanes.Bot);
Held h3 = new Held("Support", Lanes.Bot);
listBox1.Items.Add(h1);
listBox1.Items.Add(h2);
listBox1.Items.Add(h3);
*/
//Data koppelen
cbRol.DataSource = Enum.GetValues(typeof(Lanes));
}
private void btnAanmaken_Click(object sender, EventArgs e)
{
int getal;
if (CheckEmptyFields())
{
MessageBox.Show("Vul alle velden in!");
}
else
{
if (CheckMovementSpeedIsInt(out getal))
{
string naamHero = tbNaamHero.Text;
Lanes lane = ???
int mSpeedHero = getal;
Held nieuwHeld = new Held(naamHero, lane, getal);
}
}
}
private bool CheckMovementSpeedIsInt(out int getal)
{
return Int32.TryParse(tbMoveSpeed.Text, out getal);
}
private bool CheckEmptyFields()
{
return tbNaamHero.Text == null || tbMoveSpeed.Text == null || cbRol.SelectedItem == null;
}
Held:
class Held
{
private string Naam;
private Lanes Lane;
int MSpeed;
public Held(string aNaam, Lanes aLane, int aMSpeed)
{
this.Naam = aNaam;
this.Lane = aLane;
this.MSpeed = aMSpeed;
}
public override string ToString()
{
return this.Naam + " " + this.Lane.ToString();
}
}
}
Lanes:
enum Lanes
{
Top,
Mid,
Bot,
Jungle
}
Alright! So as you can see I have combined the enum with the ComboBox. I'd like to put the selected value (when the user has pressed the button "Aanmaken/Create") in the instance.
How am I able to convert the object (from ComboBox) to a type (Lanes)?
If I haven't clarified enough, just give me a heads up!
PS: The "???" in the code is the place where I'm not sure what to put since that's the question hehe.
Just use the following:
Lanes lane = (Lanes)cbRol.SelectedIndex;
This works due to enum is typeof int, so your Top is actually 0, and so on...
You can parse your Enum.Parse
Lanes lange = (Lanes) Enum.Parse(typeof(Lanes), cbRol.SelectedItem.ToString(), true);
This also works for index
Lanes lange = (Lanes) Enum.Parse(typeof(Lanes), cbRol.SelectedIndex.ToString(), true);

How to prevent crashing from a invalid input in C#

I made a simple application to add 2 numbers together but when I add two letters together or a invalid sign it crashes the program. How do I create a message box showing something saying "please put in a number" when someone inserts a letter
Here's my code:
public partial class frmAdd : Form
{
string first;
string second;
public frmAdd()
{
InitializeComponent();
}
private void btnFirst_Click(object sender, EventArgs e)
{
first = txtNumber.Text;
}
private void btnSecond_Click(object sender, EventArgs e)
{
second = txtNumber.Text;
}
private void btnResult_Click(object sender, EventArgs e)
{
int a = Convert.ToInt32(first);
int b = Convert.ToInt32(second);
int c = a + b;
txtResult.Text = c.ToString();
}
}
Use TryParse instead:
private void btnResult_Click(object sender, EventArgs e)
{
int a, b;
if (int.TryParse(first, out a) && int.TryParse(second, out b))
{
int c = a + b;
txtResult.Text = c.ToString();
}
else
{
MessageBox.Show("Invalid Input!");
}
}
Or perhaps a better method would be to trap the error when the user first inputs the data:
public partial class frmAdd : Form
{
int first; // changed to int
int second;
private void btnFirst_Click(object sender, EventArgs e)
{
if (!int.TryParse(txtNumber.Text, out this.first))
{
MessageBox.Show("Invalid Input!");
}
}
private void btnSecond_Click(object sender, EventArgs e)
{
if (!int.TryParse(txtNumber.Text, out this.second))
{
MessageBox.Show("Invalid Input!");
}
}
private void btnResult_Click(object sender, EventArgs e)
{
int c = first + second;
txtResult.Text = c.ToString();
}
}
You can use NumericUpDown control instead of TextBox - it will not allow user to input invalid data.
Or you can add validation to TextBox value after user entered something. Add ErrorProvider to your form. And subscribe to Validating event of txtNumber textbox. This event will occur when textbox loses focus. If entered text is not an integer, then error will be shown near texbox, and your button will not be clicked:
private void txtNumber_Validating(object sender, CancelEventArgs e)
{
int value;
if (!Int32.TryParse(txtNumber.Text, out value))
{
errorProvider1.SetError(txtNumber, "Value is not an integer");
return;
}
errorProvider1.SetError(txtNumber, "");
first = value; // it's better to save integer value than text
}
Validation looks like:
You can add a bit of validation to check if you can create an int from the string value passed in.
int.TryParse is a simple way of doing this.
And for the MessageBox you can just use the MessageBox calss
Example:
private void btnResult_Click(object sender, EventArgs e)
{
int a = 0;
int b = 0;
if (!int.TryParse(first, out a))
{
MessageBox.Show("first is not a number");
return;
}
if (!int.TryParse(second, out b))
{
MessageBox.Show("second is not a number");
return;
}
int c = a + b;
txtResult.Text = c.ToString();
}
Instead of using Convert.ToInt32(string), you might actually use Int32.tryParse(String, out int), as shown below:
int a, b;
a = Int32.tryParse(first, out a);
b = Int32.tryParse(second, out b);
If the conversion fails, the tryParse method will result in a zero. If it succeeds, it will give you the number which is to be found in the string.
Hope it helped you out, had to find this too in my first few days of C#.

Callback function to check the state of an integer

I'm making a WP7-app for my programming class and I want to implement a callback function for checking the state of an integer and not calling the function for checking it explicitly. The integer iterates at the push of a button and when it reaches it's max input I would like to have a callback function checking this, but I'm not completely sure how to implement it.
private void Right_Button_Click(object sender, RoutedEventArgs e)
{
if (current_input <= MAX_INPUT)
{
user_input[current_input] = 3;
current_input++;
display_result();
}
}
#endregion
void display_result()
{
//will move alot of this to the a result page
DateTime time_end = DateTime.Now;
TimeSpan difference = time_end.Subtract(timer);
time_stamp = difference.ToString();
bool combination_error = true;
if (current_input == 4)
{
for (int i = 0; i < MAX_INPUT; i++)
{
if (user_input[i] != combination[i])
{
combination_error = false;
break;
}
}
if (combination_error)
{
MessageBox.Show("Correct combination The timer is " + time_stamp);
}
else
{
MessageBox.Show("Wrong combination");
}
}
}
It's after I increment current_input that I now explicitly call display result something I wish not to do and instead create a callback function for it.
You can't really put a callback function on an integer, however, you could expose your integer as a property and call a function from the property setter. Look at this example:
private int _myInteger = 0;
private int MyInteger {
get
{
return _myInteger;
}
set
{
_myInteger = value;
if (_myInteger <= MAX_INPUT)
MyCallBackFunction();
}
}
private void Right_Button_Click(object sender, RoutedEventArgs e)
{
MyInteger = MyInteger + 1;
// Do your other stuff here
}
private void MyCallBackFunction()
{
// This function executes when your integer is <= MAX_VALUE
// Do Whatever here
display_result();
}
What this is doing is exposing your integer through a private property. As long as you set the property through the setter (e.g. use the MyInteger = MyInteger + 1; syntax), you can have your setter check the condition and execute your call back function.

Categories

Resources