I'm trying to make it so no matter what, when I push Space, a certain block of code is executed (cmd_play, to be exact).
However, it only seems to work once if you do it using Form Keypress:
private void frmmain_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == Convert.ToChar(Keys.Space))
cmdPlay_Click(null, null);
}
any ideas?
Try to set the Handled property of KeyPressEventArgs to true. Not sure if it'll fix your issue but it is good form. More info here
private void frmmain_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == Convert.ToChar(Keys.Space))
{
cmdPlay_Click(null, null);
e.Handled = true;
}
}
If that doesn't work then keyboard event hooks definitely will. Though hooking events is a much larger and more dangerous undertaking.
Are you sure that cmdPlay_Click() isn't the problem? I.E. the event handler IS getting called multiple times but cmdPlay_Click() is only playing once?
Related
Sorry, this may be a duplicate question, but I couldnot understand the solutions already provided in different answers.
I have created a mp3 player in a different manner, it plays one mp3 file at a time but one listbox have the chapters, which is not only handling to move position of that particular mp3 but also changes a picturebox image. Now somewhere I need to change the selection of the listbox from a seekbar but dont want to fire the following event of;
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
Please guide.
One way to inhibit your selection indexed change event doing its normal way is to use a boolean flag. Also, make sure that this inhibition does not stay around when some exception is raised:
private bool inhibit = true;
private void doSomeProcessWithInhibit()
{
try
{
inhibit = true;
// processing comes here
}
// if something goes wrong, make sure other functionality is not blocked
finally
{
inhibit = false;
}
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
// fast return to reduce nesting
if (inhibit)
return;
// do event handling stuff here
}
P.S. Try to use meaningful names for controls (check listBox1). You will thank yourself when revisiting the code and/or others have to.
Add a Boolean with class scope called something like isProcessing. Set it to true. Do your work, then set it to false. Warp your event in the Boolean:
bool isProcessing = true;
private void switchControls(){
isProcessing = true;
//do work;
isProcessing = false;
}
private void MyControl.OnEvent(object sender, EventArgs e){
if(!isProcessing){
//what you would normally do
}
}
OR....
Deregister the event, the re-register it
private void switchControls(){
myButton1.OnClick -= myButtonClick;
//do work
myButton1.OnClick += myButtonClick;
}
Basically, what I am trying to achieve here is that if a 'button' that I have created is pressed, it prints a character on a 'text block' and soon as I release it, it prints another on it. This is a small part of an application that I am building. But, the problem is my events never get executed, it works fine when I use Click event for the button though, but, it doesn't solve the purpose. So, I need some help with this. I read online that I have to set up Control.IsInputKey method but, I am not able to set it up being a newbie. So, please help me through it and I'll be grateful to you for making my work easier.
This is the code that I am using in this context where 'command' is the name assigned to the TextBlock and 'test' is the name assigned to my Button.
private void test_KeyDown(object sender, KeyEventArgs e)
{
command.Text = "Y";
}
private void test_KeyUp(object sender, KeyEventArgs e)
{
command.Text = "N";
}
Well, first you need to deside on which key you want theese events to fire. Your code right now, does nothing since you don't check which key is pressed. To do so you need to do this:
private void test_KeyDown(object sender, KeyEventArgs e)
{
if(e.Key == System.Windows.Input.Key.SomeKey)
command.Text = "Y";
}
private void test_KeyUp(object sender, KeyEventArgs e)
{
if(e.Key == System.Windows.Inpput.Key.SomeKey)
command.Text = "N";
}
I have a disabled control. I still want the key down and key up events to get fired off, because I would like to be aware of a certain key.
When I tested this out, it seems like none of the control's events get fired. Any ideas on how to get around this?
Lack of interaction is basic idea of disabling control, it is working as intended.
You might use KeyPreview property of Form and then launch event handlers of your disabled control from Form events.
As usually, there is n+1 ways to achieve what you seek for. So I will present only some of them.
1 - Manipulate Focus. Although easy to implement, it is also volatile as user can manipulate focus as well.
private void button_KeyDown(object sender, KeyEventArgs e)
{
((Control)sender).Controls.Add(helpBox);
((Control)sender).Focus(); // Set focus back to control so its KeyUp will be called
}
private void button_KeyUp(object sender, KeyEventArgs e)
{
((Control)sender).Controls.Remove(helpBox);
}
2 - Multiple calls to same event handler. Yes, it is possible. A bit more complicated and might depend on helpBox control class and/or its events. Possible issues may include multiply fired up event handler, however presented code is safe to use even if such situation will occur.
private void button_KeyDown(object sender, KeyEventArgs e)
{
((Control)sender).Controls.Add(helpBox);
helpBox.KeyUp += button_KeyUp; //This will add KeyUp of our hosting button to hosted control, which means that said KeyUp handler can be raised by both helpBox and button
}
private void button_KeyUp(object sender, KeyEventArgs e)
{
((Control)sender).Controls.Remove(helpBox);
helpBox.KeyUp -= button1_KeyUp; // to avoid unnecessary calls event handler can be easily "subtracted" from helpBox
}
3 - Master control by Form itself by use of KeyPreview set to true, shows controls with "help_" as helpBoxes on controls named .
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.F1)
{
foreach (Control c in this.Controls)
{
string hName = "help_" + c.Name;
Control[] help = this.Controls.Find(hName, true);
if (help.Length>0)
{
c.Controls.Add(help[0]);
}
}
}
}
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.F1)
{
foreach (Control c in this.Controls)
{
string hName = "help_" + c.Name;
Control[] help = c.Controls.Find(hName, true);
if (help.Length > 0)
{
c.Controls.Remove(help[0]);
}
}
}
}
Note: Control on-screen position depends on its parent position (relative to top-left corner of parent), in other words, by changing parent of control (which happens during Controls.Add) control will change its position.
4 - Draw it by yourself! Manipulating controls is not always best solution, instead you might want to just draw something on control.
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
button1.Tag = true;
button1.Update();
}
private void Form1_KeyUp(object sender, KeyEventArgs e)
{
button1.Tag = false;
button1.Update();
}
// there is no reason to re-draw it constantly, Paint event will be fired when needed
private void button1_Paint(object sender, PaintEventArgs e)
{
// remember that all Tag's start as null
if (((Control)sender).Tag != null && (bool)((Control)sender).Tag == true)
{
// and when needed just paint on control drawing area (also known as Canvas)
e.Graphics.FillRectangle(Brushes.Red, 0, 0, 100, 100);
e.Graphics.DrawString("Foo!", ((Control)sender).Font, Brushes.Beige, new PointF(5, 5));
}
}
Note: Every Control have Tag property, due to it being of object type you can store in it anything you want. Which makes it universal custom property. In case you wonder about meaning of this property: it have no meaning, it is made to be user-defined.
I have added a keyPress event on a ListView. With a breakpoint on my event, I can see that most of the keys trigger the event. However, a few among which, the one I'm interested in (delete), just won't trigger my event.
Is that weird ? And no, there's no broken keys on my keyboard :D
private void listView1_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Delete)
{
ListView target = (ListView)sender;
if (target.SelectedIndices != null && target.SelectedIndices.Count > 0)
{
string ric = target.SelectedItems[0].SubItems[0].Text;
//target.Items.RemoveAt(target.SelectedIndices[0]);
ListModels.getInstance().getModel("Vols").removeRic(ric);
}
}
}
The reason for this is that the KeyPress event sends a character to the control based upon the character-key you press. However, as you'd expect, the delete key does not represent a character and is thus a non-character key.
Therefore using the KeyPress event will do nothing as you have noticed. You should use the KeyDown or KeyUp Events, either of which will work absolutely fine. The nuance being whether you want your event to fire upon pressing, or letting go of a key.
You'll want to use the KeyDown event for this.
In KeyDown use the condition as follows,
if (e.KeyCode == Keys.Delete)
{
// Your Logic....
}
Use keyDown instead; keyPress is something like a full keyDown + keyUp
The problem is that if you set EditMode property to EditOnEnter it won't fire. If you use EditOnKeyStrokeOfF2 it will fire the event
If you are looking for a solution where the user should only be able to choose from the defined items, then I believe you can do it with this:
private void DropDownRank_KeyDown(object sender, KeyEventArgs e)
{
e.SuppressKeyPress = true;
}
See this code:
private void Form1_Load(object sender, EventArgs e)
{
listView1.KeyUp += new KeyEventHandler(ListView_KeyUp);
}
/// <summary>鍵盤觸發 ListView 清單</summary>
private void ListView_KeyUp(object sender, KeyEventArgs e)
{
ListView ListViewControl = sender as ListView;
if (e.KeyCode == Keys.Delete)
{
foreach (ListViewItem eachItem in ListViewControl.SelectedItems)
{
ListViewControl.Items.Remove(eachItem);
}
}
}
I tried all the stuff mentioned above but nothing worked for me, so im posting what i actually did and worked, in the hopes of helping others with the same problem as me:
Add an event handler in the constructor:
public partial class Test
{
public Test()
{
this.RemoveHandler(KeyDownEvent, new KeyEventHandler(Test_KeyDown));
// im not sure if the above line is needed (or if the GC takes care of it
// anyway) , im adding it just to be safe
this.AddHandler(KeyDownEvent, new KeyEventHandler(Test_KeyDown), true);
InitializeComponent();
}
//....
private void Test_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Delete)
{
//your logic
}
}
}
I want to allow the user to send his message when he press enter in the textbox.
I went to search and im using the sample codes below.
Now the problem is when i press enter, the event is triggered more than once like about 4-5 times.
Someone else suggested to use keyup. I have tried keyup, keydown and keypress. All have the same problem.
How do i prevent it from firing the event more than once?
private void tbxAnswer_TextChanged(object sender, EventArgs e)
{
tbxAnswer.KeyUp += new KeyEventHandler(tbxAnswer_KeyUp);
}
private void tbxAnswer_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyValue == (char)13)
{
MessageBox.Show("Hello");
}
}
Thank you!
You are adding the KeyUp event handler multiple times (inside the TextChanged handler); therefore, when Enter is pressed, the handler executes multiple times.
What you want to do here is add the KeyUp handler just once, inside your form's constructor, just after the InitializeComponent() call:
public MyForm()
{
// other code possibly here
InitializeComponent();
// and now add the event handler:
tbxAnswer.KeyUp += new KeyEventHandler(tbxAnswer_KeyUp);
}
private void tbxAnswer_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyValue == (char)13)
{
MessageBox.Show("Hello");
}
}
This is because every time you change the text, the tbxAnswer_TextChanged is called/ fired you assign an action to the keyup event; if the text is changed 4 times then you assigned the keyup event 4 times and it increases every time you change the text.
try this out:
tbxAnswer.KeyUp += new KeyEventHandler(tbxAnswer_KeyUp);
private void tbxAnswer_TextChanged(object sender, EventArgs e)
{
}
private void tbxAnswer_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyValue == (char)13)
{
MessageBox.Show("Hello");
}
}
Change your code to this
tbxAnswer.KeyUp -= tbxAnswer_KeyUp;
tbxAnswer.KeyUp += new KeyEventHandler(tbxAnswer_KeyUp);
In your code snippet, whenever the text of the TextBox changes, another eventhandler is added to the KeyUp handler. You should only add event handlers once (for instance, just after creating the textbox).
Sara and Jon have already provided the correct answer to your specific question. But if you want to go further and get a better understanding of how and when to use any particular key handling event take a look at my article Exploring Secrets of .NET Keystroke Handling. I explain and diagram when and where each event is useful, plus provide a KeystrokeSandbox application that lets you actually watch what happens!