|
Hi Richard,
Thank you for your reply. The timeout value is stored in the web.config file and after reviving OrigionalGriff's post I went and stored the value, taken from the web.config file and stored it in a session variable.
It appears to be the same solution you propose, which I'm happy to hear as it seems to be the best way to go about it.
Thank you again,
Mel
|
|
|
|
|
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...
|
|
|
|
|
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.
|
|
|
|
|
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.
|
|
|
|
|
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.
|
|
|
|
|
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 think I found the solution, being
number = Convert.ToInt32(btn.Tag);
modified on Monday, February 14, 2011 10:08 AM
|
|
|
|
|
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 an int ... 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:
private void CalculatorDigitButtonClick(object sender, EventArgs e)
{
CalculatorDigitButton calculatorDigitButton = sender as CalculatorDigitButton;
if (calculatorDigitButton != null)
{
}
}
private void CalculatorFunctionButtonClick(object sender, EventArgs e)
{
CalculatorFunctionButton calculatorFunctionButton = sender as CalculatorFunctionButton;
if (calculatorFunctionButton != null)
{
}
}
|
|
|
|
|
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 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.
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 calling Parse would just bug me!
Using Tag 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.
|
|
|
|
|
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.
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
|
|
|
|
|
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++.
|
|
|
|
|
I am working in c#. I want to change the colour of button by applying function of timer but is giving error.Can any one solve this problem?? Here is the code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication1
{
public partial class Form1 : Form
{
System.Timers.Timer greentimer;
System.Timers.Timer redtimer;
public Form1()
{
InitializeComponent();
greentimer = System.Timers.Timer(3000);
greentimer.Elapsed += new System.Timers.ElapsedEventHandler(greenTimer_Elapsed);
greentimer.Start();
redtimer = System.Timers.Timer(3000);
redtimer.Elapsed += new System.Timers.ElapsedEventHandler(redTimer_Elapsed);
redtimer.Start();
}
void redTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
Application.Exit();
}
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
}
}
Error:
Error 1 Program 'C:\Documents and Settings\XPPRESP3\Local Settings\Application Data\Temporary Projects\WindowsApplication1\obj\Debug\WindowsApplication1.exe' has more than one entry point defined: 'WindowsApplication1.Form1.Main()' C:\Documents and Settings\XPPRESP3\Local Settings\Application Data\Temporary Projects\WindowsApplication1\Form1.cs 40 21 WindowsApplication1
|
|
|
|
|
Usually when you create a new WinForm project the code to instantiate the form will be placed in a main method in a class called Program.cs. Now you have a second entry point (Main method) in your executable. I don't think this has to be a problem as long as you specify in your project properties file which ojbect should provide the entry point.
Modified:
On the project properties dialog change to the application tab and set "Start Object" property to the according object. In your case if you want to use the Main method of your form then choose the Form1 object. As a standard this is set to "Not Set" and if there's more that one entry point the copmiler complains as it is unable to resolve this on its own. Using the command line compiler your can use the /main flag to specify which object is supposed to be the "Start Object".
End Modification
Cheers!
|
|
|
|
|
Thanks but After setting the properties tab it is still giving the following errors:
here is the code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication1
{
public partial class Form1 : Form
{
System.Timers.Timer greentimer;
System.Timers.Timer redtimer;
public Form1()
{
InitializeComponent();
greentimer = System.Timers.Timer(3000);
greentimer.Elapsed += new System.Timers.ElapsedEventHandler(greenTimer_Elapsed);
greentimer.Start();
redtimer = System.Timers.Timer(3000);
redtimer.Elapsed += new System.Timers.ElapsedEventHandler(redTimer_Elapsed);
redtimer.Start();
}
void redTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
button1.Invoke(new Action(() => button1.BackColor=Color.Green));
}
private void button1_Click(object sender, EventArgs e)
{
Application.Exit();
}
[STAThread]
static void Main()
{
Application.Run( Form1);
}
}
}
Errors:
Error 1 Invalid expression term ')' C:\Documents and Settings\XPPRESP3\Local Settings\Application Data\Temporary Projects\WindowsApplication1\Form1.cs 30 41 WindowsApplication1
Error 2 Invalid expression term '>' C:\Documents and Settings\XPPRESP3\Local Settings\Application Data\Temporary Projects\WindowsApplication1\Form1.cs 30 44 WindowsApplication1
Error 3 ) expected C:\Documents and Settings\XPPRESP3\Local Settings\Application Data\Temporary Projects\WindowsApplication1\Form1.cs 30 46 WindowsApplication1
Error 4 ; expected C:\Documents and Settings\XPPRESP3\Local Settings\Application Data\Temporary Projects\WindowsApplication1\Form1.cs 30 75 WindowsApplication1
Error 5 Invalid expression term ')' C:\Documents and Settings\XPPRESP3\Local Settings\Application Data\Temporary Projects\WindowsApplication1\Form1.cs 30 75 WindowsApplication1
Error 8 'System.Timers.Timer' is a 'type', which is not valid in the given context C:\Documents and Settings\XPPRESP3\Local Settings\Application Data\Temporary Projects\WindowsApplication1\Form1.cs 19 40 WindowsApplication1
Error 9 The name 'greenTimer_Elapsed' does not exist in the current context C:\Documents and Settings\XPPRESP3\Local Settings\Application Data\Temporary Projects\WindowsApplication1\Form1.cs 20 73 WindowsApplication1
Error 10 'System.Timers.Timer' is a 'type', which is not valid in the given context C:\Documents and Settings\XPPRESP3\Local Settings\Application Data\Temporary Projects\WindowsApplication1\Form1.cs 23 38 WindowsApplication1
Error 11 'WindowsApplication1.Form1' is a 'type' but is used like a 'variable' C:\Documents and Settings\XPPRESP3\Local Settings\Application Data\Temporary Projects\WindowsApplication1\Form1.cs 42 30 WindowsApplication1
|
|
|
|
|
There are a few problems here:
First, the one you are telling us about: Remove the function at the bottom of your class.
There is already a Main function defined in Program.cs - leave it there and get rid of the one you added.
Secondly, you need a new keyword or two:
greentimer = new System.Timers.Timer(3000);
...
redtimer = new System.Timers.Timer(3000);
I would also change the intervals so they weren't the same: otherwise you won't see one colour at all! Try 3000 and 5000 instead.
And just to be picky, you don't need the invoke, but you do need another close parenthesis...
Real men don't use instructions. They are only the manufacturers opinion on how to put the thing together.
Digital man: "You are, in short, an idiot with the IQ of an ant and the intellectual capacity of a hose pipe."
|
|
|
|
|
Thanks but after removing the main function it is still giving me the following errors:
Here is the code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication1
{
public partial class Form1 : Form
{
System.Timers.Timer greentimer;
System.Timers.Timer redtimer;
public Form1()
{
InitializeComponent();
greentimer = System.Timers.Timer(3000);
greentimer.Elapsed += new System.Timers.ElapsedEventHandler(greenTimer_Elapsed);
greentimer.Start();
redtimer = System.Timers.Timer(3000);
redtimer.Elapsed += new System.Timers.ElapsedEventHandler(redTimer_Elapsed);
redtimer.Start();
}
void redTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
button1.Invoke(new Action(() =&gt; button1.BackColor=Color.Green));
}
private void button1_Click(object sender, EventArgs e)
{
Application.Exit();
}
}
}
Errors:
Error 1 Invalid expression term ')' C:\Documents and Settings\XPPRESP3\My Documents\Visual Studio 2005\Projects\WindowsApplication2\WindowsApplication2\Form1.cs 30 41 WindowsApplication2
Error 2 Invalid expression term '>' C:\Documents and Settings\XPPRESP3\My Documents\Visual Studio 2005\Projects\WindowsApplication2\WindowsApplication2\Form1.cs 30 44 WindowsApplication2
Error 3 ) expected C:\Documents and Settings\XPPRESP3\My Documents\Visual Studio 2005\Projects\WindowsApplication2\WindowsApplication2\Form1.cs 30 46 WindowsApplication2
Error 4 ; expected C:\Documents and Settings\XPPRESP3\My Documents\Visual Studio 2005\Projects\WindowsApplication2\WindowsApplication2\Form1.cs 30 75 WindowsApplication2
Error 5 Invalid expression term ')' C:\Documents and Settings\XPPRESP3\My Documents\Visual Studio 2005\Projects\WindowsApplication2\WindowsApplication2\Form1.cs 30 75 WindowsApplication2
Error 6 ; expected C:\Documents and Settings\XPPRESP3\My Documents\Visual Studio 2005\Projects\WindowsApplication2\WindowsApplication2\Form1.cs 30 76 WindowsApplication2
Error 8 'System.Timers.Timer' is a 'type', which is not valid in the given context C:\Documents and Settings\XPPRESP3\My Documents\Visual Studio 2005\Projects\WindowsApplication2\WindowsApplication2\Form1.cs 19 40 WindowsApplication2
Error 9 The name 'greenTimer_Elapsed' does not exist in the current context C:\Documents and Settings\XPPRESP3\My Documents\Visual Studio 2005\Projects\WindowsApplication2\WindowsApplication2\Form1.cs 20 73 WindowsApplication2
Error 10 'System.Timers.Timer' is a 'type', which is not valid in the given context C:\Documents and Settings\XPPRESP3\My Documents\Visual Studio 2005\Projects\WindowsApplication2\WindowsApplication2\Form1.cs 23 38 WindowsApplication2
Error 11 'WindowsApplication1.Form1' is a 'type' but is used like a 'variable' C:\Documents and Settings\XPPRESP3\My Documents\Visual Studio 2005\Projects\WindowsApplication2\WindowsApplication2\Form1.cs 42 30 WindowsApplication2
|
|
|
|
|
Look at your error messages:
Error 1 Invalid expression term ')' C:\Documents and Settings\XPPRESP3\My Documents\Visual Studio 2005\Projects\WindowsApplication2\WindowsApplication2\Form1.cs 30 41 WindowsApplication2
Error 1
This means it is an Error, not a Warning: compilation cannot continue. It is error number "1" or however many the compiler will find.
Invalid expression term ')'
This tells you what the compiler does not like: in this case it was not expecting a ")" here
C:\Documents and Settings\XPPRESP3\My Documents\Visual Studio 2005\Projects\WindowsApplication2\WindowsApplication2\Form1.cs
The file that has the error.
30
The line number in the file that the compiler is complaining about
41
The column of the line that the error was noticed in.
WindowsApplication2
The Project that the problem was found in.
Now, with all that, can you work out what you should do next?
Right: Find the line. It is line 30: Use CTRL+G to go to line 30.
button1.Invoke(new Action(() => button1.BackColor=Color.Green));
Look at column 41.
button1.Invoke(new Action(() => button1.BackColor=Color.Green));
^
|
What does the compiler expect there?
Some kind of expression, given that it is inside a "("...")" pair.
And so on. I am not going to sit here and explain in great detail every nuance of every compiler error: you have to do something yourself!
In this case, ditch the Invoke . Replace the line with:
button1.BackColor=Color.Green;
Then provide a matching handler routine for your greenTimer ...
Real men don't use instructions. They are only the manufacturers opinion on how to put the thing together.
Digital man: "You are, in short, an idiot with the IQ of an ant and the intellectual capacity of a hose pipe."
|
|
|
|
|
Apart from the answers give by others, when you originally asked this question (just a few hours ago), apart from the fact that you were given a solution, you stated that you wanted the colour change intervals to be random. So, rather than using a literal in the Timer constructor you should be looking to use the Random class to get different timings for each button. You might also change that to a new interval in the Elapsed event handlers.
BTW you don't seem to have a handler for the green timer in the code you posted.
Henry Minute
Do not read medical books! You could die of a misprint. - Mark Twain
Girl: (staring) "Why do you need an icy cucumber?"
“I want to report a fraud. The government is lying to us all.”
I wouldn't let CG touch my Abacus!
When you're wrestling a gorilla, you don't stop when you're tired, you stop when the gorilla is.
|
|
|
|
|
on top of all that, you're using the wrong kind of timer. You should use a Windows.Forms.Timer which ticks on the GUI thread.
This is what I would do:
- have a single timer ticking every second;
- have a single random generator;
- within the tick handler use the Random three times:
= once to decide whether you want to do something at that time (say 70% no);
= once to choose which button to change (say equal probability for each of the buttons);
= once to choose which new color to apply (say equal probability for each of a predefined list of colors).
PS: I would hate an app that does all that!
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.
|
|
|
|
|
Luc Pattyn wrote: PS: I would hate an app that does all that!
Don't say that. I'll have to go back and alter all of my code.
Henry Minute
Do not read medical books! You could die of a misprint. - Mark Twain
Girl: (staring) "Why do you need an icy cucumber?"
“I want to report a fraud. The government is lying to us all.”
I wouldn't let CG touch my Abacus!
When you're wrestling a gorilla, you don't stop when you're tired, you stop when the gorilla is.
|
|
|
|
|
user experience pevails on developer comfort.
zillions of users should not suffer from your mistakes and laziness.
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 have read the initial post and the replies of the thread. I would like to say, just as a piece of advise, if you are about to post here each and every compile error you get without even reading it in order to get your code working, you will need at least one month to develop the "Hello world" application. This compile error is telling you that "Program ... has more than one entry point defined". Just this[^] would have solved your problem.
|
|
|
|
|