Simple calculator
-
Thanks for replying. And how do you link all buttons in a handler? Maybe by putting them inside a groupBox? I tried it so but didn't work. Where does the Method 'AnyDigitButton_Clicked' come from?
You add a handler to each of the buttons click event, but that handler can be created from the same function. That's it.
-
Thanks for replying. And how do you link all buttons in a handler? Maybe by putting them inside a groupBox? I tried it so but didn't work. Where does the Method 'AnyDigitButton_Clicked' come from?
The details depend on the IDE you use. How do you usually tell your app to execute some event handler when some event occurs? you normally can choose the handler's name, choosing a pre-existing one should also be possible.
nstk wrote:
Maybe by putting them inside a groupBox?
Nope. GroupBoxes do have their use, especially with RadioButtons, here they most likely don't.
nstk wrote:
Where does the Method 'AnyDigitButton_Clicked' come from?
I wrote it; it should show you all it takes is just a few lines of code. :)
Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
-
Hallo everyone, I want to make a Simple calculator, as an exercise to get familiar with GUI and C# I can easily drag 10 buttons, name them btn1, btn2... btn0 and then create the appropriate functions like
private void btn1_Click(object sender, EventArgs e)
and let a member variable have the appropriate value. But... isn't there a better way to deal with that? Something like having an array[9], where every field is a button, or sort of it? I find it ugly and really annoying having 10 functions who do quite the same thing. Thanks...
If you're using Visual Studio, select the button then in the Properties window click the events icon. In the dropdown next to the event (Click in this case) you can select any method with the correct signature. Selecting the same method for all button's click event will result in the same handler being called. To get the value, as Luc said you can use the Tag property - although I would be tempted to add a more suitable property such as
Value
which would hold anint
... something like this:using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;public class CalculatorDigitButton : Button
{
public const int MaxValue = 9;
public const int MinValue = 0;public CalculatorDigitButton() { base.Text = "0"; } private int value; \[Browsable(false)\] public new string Text { get { return base.Text; } set { } } public int Value { get { return value; } set { if (value < MinValue || value > MaxValue) throw new ArgumentOutOfRangeException( "value", string.Format("Value must be between {0} and {1}", MinValue, MaxValue)); this.value = value; base.Text = value.ToString(); } }
}
public enum CalculatorFunction
{
Add,
Subtract,
Multiply,
Divide
}public class CalculatorFunctionButton : Button
{
private static readonly List<string> FunctionText = new List<string>(4){
"+", "-", "*", "/" };private CalculatorFunction function; public CalculatorFunctionButton() { base.Text = FunctionText\[0\]; } public CalculatorFunction Function { get { return function; } set { if (!Enum.IsDefined(typeof(CalculatorFunction), value)) throw new ArgumentException( "Function must be a defined value", "Function"); function = value; base.Text = FunctionText\[(int)function\]; } } \[Browsable(false)\] public new string Text { get { return base.Text; } set { } }
}
Your event handlers for these may look something like this:
// Assign each digit button's click event to this handler private void CalculatorDigitButtonC
-
If you're using Visual Studio, select the button then in the Properties window click the events icon. In the dropdown next to the event (Click in this case) you can select any method with the correct signature. Selecting the same method for all button's click event will result in the same handler being called. To get the value, as Luc said you can use the Tag property - although I would be tempted to add a more suitable property such as
Value
which would hold anint
... something like this:using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;public class CalculatorDigitButton : Button
{
public const int MaxValue = 9;
public const int MinValue = 0;public CalculatorDigitButton() { base.Text = "0"; } private int value; \[Browsable(false)\] public new string Text { get { return base.Text; } set { } } public int Value { get { return value; } set { if (value < MinValue || value > MaxValue) throw new ArgumentOutOfRangeException( "value", string.Format("Value must be between {0} and {1}", MinValue, MaxValue)); this.value = value; base.Text = value.ToString(); } }
}
public enum CalculatorFunction
{
Add,
Subtract,
Multiply,
Divide
}public class CalculatorFunctionButton : Button
{
private static readonly List<string> FunctionText = new List<string>(4){
"+", "-", "*", "/" };private CalculatorFunction function; public CalculatorFunctionButton() { base.Text = FunctionText\[0\]; } public CalculatorFunction Function { get { return function; } set { if (!Enum.IsDefined(typeof(CalculatorFunction), value)) throw new ArgumentException( "Function must be a defined value", "Function"); function = value; base.Text = FunctionText\[(int)function\]; } } \[Browsable(false)\] public new string Text { get { return base.Text; } set { } }
}
Your event handlers for these may look something like this:
// Assign each digit button's click event to this handler private void CalculatorDigitButtonC
That's a lot of code to avoid an
(int)
cast, as that is what the specialized button class is basically doing. And I just realized, the digit buttons probably have a simple numeric Text property already, so maybeint.Parse(btn.Text)
is the better approach. Keep in mind it will execute less than once per second as it is an input part of the GUI. :)Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
-
That's a lot of code to avoid an
(int)
cast, as that is what the specialized button class is basically doing. And I just realized, the digit buttons probably have a simple numeric Text property already, so maybeint.Parse(btn.Text)
is the better approach. Keep in mind it will execute less than once per second as it is an input part of the GUI. :)Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
You're right of course, but I always try to take the approach, if it's a value it should be stored as a value. If I want to display a string representation, then I do it by calling
ToString
or whatever on the value. Using the Text property as the value by callingParse
would just bug me! UsingTag
would be preferable to that as it's just simple boxing/unboxing, but when subclassing is so easy and the auto Text mechanism (plus any other functionality required) can then be built in, that's the way I would go.Dave
Binging is like googling, it just feels dirtier. Please take your VB.NET out of our nice case sensitive forum. Astonish us. Be exceptional. (Pete O'Hanlon)
BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn) -
You're right of course, but I always try to take the approach, if it's a value it should be stored as a value. If I want to display a string representation, then I do it by calling
ToString
or whatever on the value. Using the Text property as the value by callingParse
would just bug me! UsingTag
would be preferable to that as it's just simple boxing/unboxing, but when subclassing is so easy and the auto Text mechanism (plus any other functionality required) can then be built in, that's the way I would go.Dave
Binging is like googling, it just feels dirtier. Please take your VB.NET out of our nice case sensitive forum. Astonish us. Be exceptional. (Pete O'Hanlon)
BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)I'm a bit concerned that you won't stand a chance against Asian competition if you need specialized buttons for a simple calculator; it sounds all too expensive. There is a balance to strike between design principles and economic considerations. :laugh:
Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
-
several Controls can share some handler, and Controls have a nice Tag property where you can store whatever you like. So it could be:
AnyDigitButton_Clicked(object sender, EventArgs e) {
Button btn=sender as Button;
number=10*number+(int)btn.Tag;
}:) PS: there are lots of articles on calculators around, search CodeProject or Google, and see how they do it.
Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
I did the above by adding the 'AnyDigitButton_Clicked' as a handler to the Click Event, but I get the following error: When casting from a number, the value must be a number less than infinity :( A declaration of number as
int number = 0;
inside or outside the function didn't change anything...
-
I did the above by adding the 'AnyDigitButton_Clicked' as a handler to the Click Event, but I get the following error: When casting from a number, the value must be a number less than infinity :( A declaration of number as
int number = 0;
inside or outside the function didn't change anything...
-
That's a lot of code to avoid an
(int)
cast, as that is what the specialized button class is basically doing. And I just realized, the digit buttons probably have a simple numeric Text property already, so maybeint.Parse(btn.Text)
is the better approach. Keep in mind it will execute less than once per second as it is an input part of the GUI. :)Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
And I just realized, the digit buttons probably have a simple numeric Text property already, so maybe int.Parse(btn.Text) is the better approach. Keep in mind it will execute less than once per second as it is an input part of the GUI. Yes it is. I tried it and it works perfectly. Thank you all for the great help!
modified on Monday, February 14, 2011 4:49 PM
-
Hallo everyone, I want to make a Simple calculator, as an exercise to get familiar with GUI and C# I can easily drag 10 buttons, name them btn1, btn2... btn0 and then create the appropriate functions like
private void btn1_Click(object sender, EventArgs e)
and let a member variable have the appropriate value. But... isn't there a better way to deal with that? Something like having an array[9], where every field is a button, or sort of it? I find it ugly and really annoying having 10 functions who do quite the same thing. Thanks...
Personally, I wouldn't bother with the (previously suggested) Tag property...the first handler parameter is sender - which is the control that the event originated from...no need for a tag when you already have sufficient info in there to determine which one was clicked.
C# has already designed away most of the tedium of C++.