Skip to main content
gamedev.net
🔒 Locked

C# KeyDown problem

Started by NotSlyPee Mar 17, 2007 at 12:25 PM 14 replies 12.9k views
Original Post
NotSlyPee
NotSlyPee
I can't get KeyDown method to work. I need my application to check answer when user clicks 'enter' on his keyboard, but unfortunately nothing happens. Here's the code:
 private void Answer_KeyDown(object sender, KeyEventArgs e)
        
        {
            if (e.KeyCode == Keys.Enter)
            {
                int result = 0;
                if (problemType == "+")
                {
                    result = no1 + no2;
                }
                else if (problemType == "-")
                {
                    result = no1 - no2;
                }
                else if (problemType == "*")
                {
                    result = no1 * no2;
                }

                if (Answer.Text == result.ToString())
                {
                    Feedback.Text = "Correct";
                }
                else
                {
                    Feedback.Text = "Incorrect";
                }
Nypyren
Nypyren
1. Make sure the control actually gets focus
2. If it's a TextBox or derived, there are "AcceptsReturn" and "AcceptsTab" properties that you need to set to 'true' if you want KeyDown events for those two keys.
3. In rare cases, override the "IsInputKey" method and return true for enter, otherwise return base.IsInputKey.
NotSlyPee
NotSlyPee
Quote:
Original post by Nypyren
1. Make sure the control actually gets focus
2. If it's a TextBox or derived, there are "AcceptsReturn" and "AcceptsTab" properties that you need to set to 'true' if you want KeyDown events for those two keys.
3. In rare cases, override the "IsInputKey" method and return true for enter, otherwise return base.IsInputKey.


I didn't understood the get focus part. Can you tell a bit more about it?
Nypyren
Nypyren
Well, if it's a TextBox and you're successfully typing text into it, it has focus. If you can't tell if any input is getting to it at all then it might not.

Focus means that the control is the one selected to receive keyboard events.

Typically Focus is set when you click on a control or press the TAB key to move between controls.

Various controls have their "Selectable" style (see "Control.Setstyle") true or false, which can affect this.
NotSlyPee
NotSlyPee
Thanks and yes, it has focus and "AcceptsReturn" and "AcceptsTab" properties are set to 'true'. It's still doesn't work.
Nypyren
Nypyren
Did you put a breakpoint on your event handler to make sure that any other keys work?
NotSlyPee
NotSlyPee
..not really, i'm a beginner. :D
Nypyren
Nypyren
If AcceptsReturn is true and you're not getting the keydown it's possible that the event hasn't been hooked. Your function by itself won't be called unless you added it to the event, which requires something that looks like the following line:

Answer.KeyDown += new KeyEventHandler(Answer_Keydown);

(edit) oops
NotSlyPee
NotSlyPee
Well, there's no changes to my application again.

[Edited by - NotSlyPee on March 17, 2007 3:57:11 PM]
Nypyren
Nypyren
Might be time to post all of your code...
NotSlyPee
NotSlyPee
Ok, i think posting all code was a good idea. :D Here it is:
public partial class Form1 : Form    {        Random randomNo = new Random();        int no1;        int no2;        string problemType = "+";        public Form1()        {            InitializeComponent();        }        private void StartGame_Click(object sender, EventArgs e)        {            Clock = new Timer();            Clock.Interval = 1000;            Clock.Start();            Clock.Tick += new EventHandler(Timer_Tick);            StartGame.Visible = false;            CheckAnswer.Visible = true;            Question.Visible = true;            Answer.Visible = true;            NextQuestion.Visible = true;            Feedback.Text = "";            Feedback.Visible = true;            label1.Visible = true;            Gen_Question();        }        private void Gen_Question()        {            no1 = randomNo.Next(100);            no2 = randomNo.Next(100);            if (radioButton1.Checked)            {                problemType = "+";            }            else if (radioButton2.Checked)            {                problemType = "-";            }            else if (radioButton3.Checked)            {                problemType = "*";            }            Question.Text = no1 + problemType + no2;        }        private void CheckAnswer_Click(object sender, EventArgs e)        {            int result = 0;            if (problemType == "+")            {                result = no1 + no2;            }            else if (problemType == "-")            {                result = no1 - no2;            }            else if (problemType == "*")            {                result = no1 * no2;            }            if (Answer.Text == result.ToString())            {                Feedback.Text = "Correct";            }            else            {                Feedback.Text = "Incorrect";            }        }        private void NextQuestion_Click(object sender, EventArgs e)        {            x = 30;            Clock.Start();            this.label1.Text = "" + x;            Gen_Question();            Answer.Text = "";            Feedback.Text = "";        }        int x = 30;        private void Timer_Tick(object sender, EventArgs e)        {            if (x == 1) { Clock.Stop(); }            x = x - 1;            this.label1.Text = "" + x;            if (x == 0) { stop(); }        }        private void stop()        {            this.Question.Text = "Time's Up";        }                private void Answer_KeyDown(object sender, KeyEventArgs e)                {            if (e.KeyCode == Keys.Enter)            {                int result = 0;                if (problemType == "+")                {                    result = no1 + no2;                }                else if (problemType == "-")                {                    result = no1 - no2;                }                else if (problemType == "*")                {                    result = no1 * no2;                }                if (Answer.Text == result.ToString())                {                    Feedback.Text = "Correct";                }                else                {                    Feedback.Text = "Incorrect";                }                Answer.KeyDown += new KeyEventHandler(Answer_KeyDown);            }


Once i found an error in computer generated code, so if needed i'll post it later. ;)
intrest86
intrest86
You need to add the event handler BEFORE the function can ever be called, so adding it in the function is worthless. Maybe you should do it after the call to "InitializeComponent"?

Right now what you are doing is like saying you will give directions to the pizza delivery guy when he gets to your house... it is never going to happen.
Turring Machines are better than C++ any day ^_~
NotSlyPee
NotSlyPee
Where exactly should i put event handler, because everywhere i put it 5-15 errors appear.
Nypyren
Nypyren
I usually hook events at the bottom of the form's constructor:

public Form1(){  InitializeComponent();  Answer.KeyDown += new KeyEventHandler(Answer_KeyDown);}


The "InitializeComponent" is an auto-generated function that creates all of the controls that you laid out on the Form Designer (the Form Designer writes the code for that function).

You should also look for the "Form1.Designer.cs" file and examine its contents to gain a better understanding of how the program is being set up. It may help you in the future to know exactly what's going on under the hood :)
NotSlyPee
NotSlyPee
At last it's working. Thanks guys. :)
Nypyren
Nypyren
Here's a bit of an explanation into the order of event processing for the Windows controls:

1. Old-school windows messages get sent to the application by the operating system (such as WM_KEYDOWN).

2. Each control in your application has a default message handling wrapper that converts things like WM_KEYDOWN to a function call to OnKeyDown (or dozens of other functions).

3. OnKeyDown is a virtual function, so any derived controls can override it and handle it.

4. OnKeyDown by default raises the KeyDown event after it is done with internal processing, sort of like this:

// Inside System.Windows.Forms.Control classpublic event KeyEventHandler KeyDown; // this is the event 'variable' that you get access to.virtual void OnKeyDown(KeyEventArgs kea){  if (KeyDown != null)  {    KeyDown(this, kea);  }}// Inside System.Windows.Forms.TextBoxoverride void OnKeyDown(KeyEventArgs kea){  // Code to handle TextBox specific processing would be here.    base.OnKeyDown(kea); // This eventually calls the Control.OnKeyDown function}



The "KeyDown" variable can be thought of as list of functions that get called when you "call" it. But you have to add your function to that list first, which is what "Answer.KeyDown += new KeyEventHandler(Answer_Keydown);" does. The name of the function doesn't matter at all, and doesn't get automatically added to the event's list.

So you have to add your handler function to the list somewhere early, somewhere in a function that always gets run first (like the Form's constructor), but after the TextBox actually gets created (otherwise the list won't be available yet).

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.