Ok, so in my program I tried making buttons and assigning different methods for each button pressed. But I came into a problem where I also want the user to use his keyboard and assign buttons pressed on keyboard into same buttons on screen. Yet firstly, I tried if button is pressed by mouse or keyboard yet the method doesn't allow KeyEvents in 'EventArgs' (which is fine by me), so I created different method and made a boolean variable so that if in that separate method the key is pressed, make that variable true and in that main method if that is true then perform the code, yet the program ignores that keyboard variable and I have no idea why.
Then I tried making a different class as I thought maybe that would help. Now I can call that class and method inside it but not pass a parameter as it says it's a method so it can't do anything else but only be called.
If you're curious, here's the code below...
___
// the button '1' variable
bool pressOne = false;
___
// method for if that button is pressed
private void AnyNumberClick(object sender, EventArgs e)
{
Button btnSender = (Button)sender;
if (btnSender == btn_Num1 || pressOne)
{
// if button is pressed by either, perform code
}
}
___
// method for detecting which key is pressed for certain bool variable into button's method
public void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.D1)
{
pressOne = true;
}
else
{
pressOne = false;
}
___
// Call another class inside 'From1_KeyDown' method
Class1 newclass = new Class1();
newclass.buttonused();
NumResult.Text = newclass.buttonused.num();
The one with class I don't know how to start it. I don't even know if new class will help me there or not. I did the research but didn't find the answer. I appreciate any help from this.
Try it this way. I've setup a Dictionary<Keys, Button> to represent the relationship between a Key and a Button. Then I've overridden ProcessCmdKey() to trap key presses. If the key pressed exists in our lookup, then we click it with .PerformClick():
public partial class Form1 : Form
{
private Dictionary<Keys, Button> btnLookups = new Dictionary<Keys, Button>();
public Form1()
{
InitializeComponent();
// make your key -> button assignments in here
btnLookups.Add(Keys.F1, button1);
btnLookups.Add(Keys.F2, button2);
btnLookups.Add(Keys.F3, button3);
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
Button btn;
if (btnLookups.TryGetValue(keyData, out btn))
{
btn.PerformClick();
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("button1");
}
private void button2_Click(object sender, EventArgs e)
{
MessageBox.Show("button2");
}
private void button3_Click(object sender, EventArgs e)
{
MessageBox.Show("button3");
}
}
You need an event handler to tie to your method "AnyNumberClick". This is done in the Designer.cs portion of your form. Create a character array char[] and create a function within a button pressed event method, and then compare the button pressed against the set of characters in your array.
private void txt_box_keypress(object sender, KeyPressEventArgs e)
{
char[] SomeArray = {'a','b','c', etc};
int LengthOfArray = SomeArray.Length;
for (int x = 0; x < LengthOfArray; x++)
{
if (txt_box.Text.Contains(SomeArray[x]))
{
'Your method event here'
}
}
}
Related
I am making a game where I need a constant keyboard listener (to navigate through the game). I tried getting the keyboard focus to one place and let it stay there using a seperate thread in a while true loop. This seems to crash my program.
Question:
Is there a method to get my keyboard focused on one element so I can grab my key input from there?
What can I use?:
something that works without throwing exceptions
something I can use in combination with other text input
something that doesn't take hours to compile
something that is easy to build another program (im not super good at c#)
What have I tried?
public MainWindow()
{
InitializeComponent();
Thread keyboardfocus = new Thread(GetFocus);
keyboardfocus.Start();
}
private void GetFocus()
{
while (true)
{
Keyboard.Focus(KeyboardButton);
}
}
private void KeyboardButton_OnKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Z)
{
map.PosUp -= 1;
MainCanvas.Background = Brushes.Aqua;
}
else if (e.Key == Key.S)
{
map.PosUp += 1;
MainCanvas.Background = Brushes.Black;
}
}
Thanks
Add event handler for Window.Loaded and set there a focus to the desired control:
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
Keyboard.Focus(KeyboardButton);
}
Add event handler for the UIElement.LostKeyboardFocus in your case KeyboardButton and just set the keybord focus again to the KeyboardButton:
private void KeyboardButton_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
Keyboard.Focus(KeyboardButton);
}
In my program I would need that an action is perfomed while a key is pressed. I have already searched but the solutions either were not for c#, neither for forms or I couldnt understand them.
Is there a proper and easy solution to this?
EDIT: I am using WinForms and I want that while the form is focussed and a key is pressed an action is repeatedly performed.
First off, you need to provide a bit more information and if possible some code you already tried. But nevertheless I'll try. The concept is relatively easy, you add a timer to your form, you add key_DOWN and key_UP events (not key pressed). You make a bool that resembles if key is currently pressed, you change its value to true on keydown and false on keyup. It will be true while you hold the key.
bool keyHold = false;
public Form1()
{
InitializeComponent();
}
private void timer1_Tick(object sender, EventArgs e)
{
if (keyHold)
{
//Do stuff
}
}
private void Key_up(object sender, KeyEventArgs e)
{
Key key = (Key) sender;
if (key == Key.A) //Specify your key here !
{
keyHold = false;
}
}
private void Key_down(object sender, KeyEventArgs e)
{
Key key = (Key)sender;
if (key == Key.A) //Specify your key here !
{
keyHold = true;
}
}
**If you're trying to make a simple game on forms and you're struggling with the input delay windows has (press and hold a key, it will come up once, wait and then spam the key) This solution works for that (no pause after the initial press).
You can try this.
In the Key down event you set the bool 'buttonIsDown' to TRUE and start the method 'DoIt' in an Separate Thread.
The code in the While loop inside the 'DoIt' method runs as long the bool 'buttonIsDown' is true and the Form is on Focus.
It stops when the Key Up event is fired or the Form loose the focus.
There you can see the 'buttonIsDown' is set to false so that the While loop stops.
//Your Button Status
bool buttonIsDown = false;
//Set Button Status to down
private void button2_KeyDown(object sender, KeyEventArgs e)
{
Key key = sender as Key;
if (key == Key.A)
buttonIsDown = true;
//Starts your code in an Separate thread.
System.Threading.ThreadPool.QueueUserWorkItem(DoIt);
}
//Set Button Status to up
private void button2_KeyUp(object sender, KeyEventArgs e)
{
Key key = sender as Key;
if (key == Key.A)
buttonIsDown = false;
}
//Method who do your code until button is up
private void DoIt(object dummy)
{
While(buttonIsDown && this.Focused)
{
//Do your code
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btn0_Click(object sender, EventArgs e)
{
MessageBox.Show("called btn 0 click..");
KeyPressEventArgs e0 = new KeyPressEventArgs('0');
textBox1_KeyPress(sender, e0);
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
MessageBox.Show("called txtbox_keypress event...");
}
}
Am sorry if this is a silly question,I have just started to learn windows forms, I still find material on the internet confusing.I want to implement calculator. So when number button is pressed it should be filled in textbox. So I thought calling textBox1_keypress() event from button click event would work??? but its not working,
I can manually write the logic in button click event to fill text in text box but if i do so, i have to do the same thing in button1_KeyPress event too. so it would be duplication of code right??...so i thought solution was to call textBox1_KeyPress() event from both button click event and button key press event...but its not working .So what should i do???..is there any other approach which should i follow.
so it would be duplication of code right??
Yes, it would be. So you can do
private void btn0_Click(object sender, EventArgs e)
{
CommonMethod(e);
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
CommonMethod(e);
}
private void CommonMethod(EventArgs e)
{
//Your logic here.
}
The TextBox KeyPress event handler (textBox1_KeyPress) is called after the user presses a key. The KeyPressEventArgs parameter includes information such as what key was pressed. So calling it from your btn0_Click method isn't going to set the text for the TextBox.
Rather, you want to (probably) append whatever number the user pressed to the text already present in the TextBox. Something like
private void btn0_Click(object sender, EventArgs e)
{
textBox1.Text += "0";
}
might be closer to what you're trying to accomplish.
You could put the logic in an extra function like so:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btn0_Click(object sender, EventArgs e)
{
NumberLogic(0),
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
// I don't know right now if e contains the key pressed. If not replace by the correct argument
NumberLogic(Convert.ToInt32(e));
}
void NumberLogic(int numberPressed){
MessageBox.Show("Button " + numberPressed.ToString() + " pressed.");
}
}
You don't want to tie the events together like that.
A key-press is one thing, handled in one way.
A button click is something totally different and should be handled as such.
The basic reason is this,
The button doesn't know what number it is, you need to tell it that.
A key-press on the other hand, knows what number was pressed.
If you REALLY want to, for some reason, you could use SendKeys to trigger your key-press event in a round-about way, from the button.
SendKeys.SendWait("0");
I can suggest to you to use an Tag Property of the Buttons. Put in it the value of each button in Design mode or in Constructor, create one button event handler for all buttons and use Tag value:
Constructor:
button1.Tag = 1;
button2.Tag = 2;
button1.Click += buttons_Click;
button2.Click += buttons_Click;
Event hadler:
private void buttons_Click(object sender, EventArgs e)
{
textBox1.Text = ((Button)sender).Tag.ToString();
}
I have a problem that I'm struggling with..
I want to move an image using my keyboard to the left, right, up or down and in a diagonal way.
I searched the web and found, that to use 2 diffrent keys I need to remember the previous key, so for that I'm using a bool dictionary.
in my main Form class this is how the KeyDown event looks like:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
baseCar.carAccelerate(e.KeyCode.ToString().ToLower());
carBox.Refresh(); //carbox is a picturebox in my form that store the image I want to move.
}
My KeyUp event:
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
baseCar.carBreak(e.KeyCode.ToString().ToLower());
}
My Paint event:
private void carBox_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawImage(Car, baseCar.CharPosX, baseCar.CharPosY); // Car is just an image
}
And my baseCar class:
private Dictionary KeysD = new Dictionary();
// there is a method to set the W|A|S|D Keys, like: KeysD.Add("w",false)
public void carAccelerate(string moveDir)
{
KeysD[moveDir] = true;
moveBeta();
}
public void moveBeta()
{
if (KeysD["w"])
{
this.CharPosY -= this.carMoveYSpeed;
}
if (KeysD["s"])
{
CharPosY += carMoveYSpeed;
}
if (KeysD["a"])
{
CharPosX -= carMoveXSpeed;
}
if (KeysD["d"])
{
CharPosX += carMoveXSpeed;
}
}
public void carBreak(string str)
{
KeysD[str] = false;
}
Anyway it works, but my problem is that I can't get back to the first pressed key for example:
I pressed W to move up and then the D key to go diagonal, how ever when I release the D key it wont go Up again because the KeyDown event is "dead" and wont call the carAccelerate() method again..
and I can't figure out how to fix it..
Can any one help me please?
Maybe there is a better way to handle the keys? im open to any ideas!
And I hope you can understand it, my english isnt the best :S
Store all keystates and don't animate on keypress, but for example using a timer.
Then:
KeyDown(key)
{
KeyState[key] = true;
}
KeyUp(key)
{
KeyState[key] = false;
}
Timer_Tick()
{
Animate();
}
Animate()
{
if (KeyState["W"])
{
// Accelerate
}
if (KeyState["S"])
{
// Decelerate
}
}
Then in the KeyDown method you can check for conflicting keys (what if accelerate + decelerate are pressed at the same time, and so on).
I am trying to create an application that changes the value of the button that has been pressed.
Example: If the C button on the keyboard has been pressed then it should output the value of '7'. The buttons value should only change for as long as the application is running.
My code so far:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.KeyDown += new KeyEventHandler( Form1_KeyDown );
}
void Form1_KeyDown( object sender, KeyEventArgs e )
{
if (e.KeyCode == Keys.C)
{
}
}
}
All help would greatly be appreciated.
Thanks
If this is in the scope of your application only, I would continue by making a hash map of keys to their binding. (KeyCode => Your-Binding)
If you want an integer value like in your example, you'll have a map like:
Dictionary<KeyCode,Integer> keyMap = new Dictionary<KeyCode,Integer>();
void Form1_KeyDown( object sender, KeyEventArgs e )
{
if(keyMap.ContainsKey(e.KeyCode) {
int boundValue = keyMap[e.KeyCode];
// continue with what you want to do here
}
}