I have a form with a menuStrip control (the layout VerticalStackWithOverflow). How could I enable the arrow keys to navigate this menu? Also how could I get the event of pressing Enter on the selected item?
I dont particularly know about that control, but the arrows and Enter dont work with TextBox either. The default key form moving between controls is Tab. You have to override the keypress event and add that feature by invoking SelectNextControl method something like this(in this case Enter)
private void keypressed(Object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Return)
{
this.SelectNextControl((Control) sender, true, true, true, true);
}
}
Related
I have a WinForms form with a TableLayoutPanel on it.
In this TableLayoutPanel, I have 2 Button controls.
I press one of these buttons.
Then I press the Up or Down arrow (↑ ↓) on the keyboard.
The focus jumps from one button to the other.
I don't want this behaviour.
Setting the TableLayoutPanel's "TabStop" to "False" doesn't help.
I would instead like to intercept the event and set the focus to another control manually.
However, I didn't find the event that I need to intercept.
How could I disable this jumping by arrow keys?
Which event would I have to intercept to set the focus to another control?
Thank you!
You can handle PreviewKeyDown event of all the buttons using a single handler and check if the pressed key is an arrow key, set e.IsInputKey = true and prevent focus change:
private void button1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
var keys = new[] { Keys.Left, Keys.Right, Keys.Up, Keys.Down };
if (keys.Contains(e.KeyData))
e.IsInputKey = true;
}
You can read about the behavior and the solution in Remarks section of the PreviewKeyDown documentations.
The behavior is in fact implemented in ProcessDialogKey method of the container control (you can see source code) and you can also prevent it by overriding ProcessDialogKey of the Form, like this:
protected override bool ProcessDialogKey(Keys keyData)
{
var keys = new[] { Keys.Left, Keys.Right, Keys.Up, Keys.Down };
if (keys.Contains(keyData))
return true;
else
return base.ProcessDialogKey(keyData);
}
I m working at an uni project and I encountered a problem.(I m also a beginner with C#).
I created a windows form menu and I have to choose options via keyboard. But my program won't let me choose unless i clicked on the option prior. (I have to click the option then press the key, otherwise I can even spam the key and nothing will happen).
private void button1_KeyDown(object sender, KeyEventArgs e)
{
if( e.KeyCode==Keys.D1 || e.KeyCode==Keys.NumPad1)
{
SidePanel.Height = button1.Height;
SidePanel.Top = button1.Top;
firstCustomControl1.BringToFront();
}
}
Here's a code snippet of how i choose an option based on the number.
Thank you :)
Firstly Set "KeyPreview" Option of your form on which you tend to perform action to true, it is false by default. It needs to be true to perform any function based on any keyboard event.
Secondly add Keydown event on same form.
private void YourForm_KeyDown(object sender, KeyEventArgs e)
{
YourCodeHere();
}
don't use the Keydown event on your Button!
Select the Form in the designer and add Keydown Event for entire Form.
Add Key Down Event on Form 1
then add your Code to the following auto generated Method
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
YourCodeHere();
}
Hopefully there is a pretty easy solution to this.
I have a program where the user has to click next a lot to move through a setup process.
What's the best way to maintain focus on the next button while the user enters info in text boxes?
Well, that depends on the design, but it shouldn't be a problem marking your button as "default". In winforms it's called "AcceptButton" if I'm not mistaken.
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.acceptbutton%28v=VS.100%29.aspx
A way around is handling the return key for each text box. So when the user presses enter key, it can simulate pressing next button.
First move your code in the next button to a void.
private void GoNext()
{
//Do something
}
private void btnNext_Click(object sender, EventArgs e)
{
GoNext();
}
Now handle the key press.
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Return)
{
e.Handled = true;
GoNext();
}
}
You may also draw focus rectangle in the lost focus event of next button for visual purposes.
i am working with DataGridView trying to provide specific utility to my user...
what i want to do is when some key is presses instead of the normal function that the key was supposed to perform like updown arrows and page up down keys etc i want to stop the default action
like when on a selected row, datagrid in selectfullrow, when down arrow is press it shouldn't change the row selection or goto the next row
You should handle the KeyDown event and set the e.Handled to true to disable the default action:
private void dataGridView1_KeyDown(object sender, KeyEventArgs e) {
e.Handled = e.KeyCode == Keys.Down;
}
If I do not create an "Edit->Copy" menu item and assign it the shortcut keys "CTRL+C", then I can select a control (RichTextBox, DataGridView, etc..) and hit "CTRL+C" and the control itself will handle the copy. I can copy text out, and paste it into notepad, etc..
Now throughout my whole form, I have a lot of controls. But I have a custom control that I want to make clear that I handle Copy functionality for. So I added the ShortcutKey CTRL+C to Edit->Copy, and by default it is set to Enabled.
Now, I have to implement an event handler for the 'click' event on that menu item. If I explicitly put in code to handle the copy, then it works:
public void menuEditCopy_Click(object sender, EventArgs e)
{
myCustomControl.Copy();
}
However, now Copy does not work on any other type of control. My first inclination was to find out the type of control that has focus, and implement a limited set of copy code for each of them:
public void menuEditCopy_Click(object sender, EventArgs e)
{
if (this.ActiveControl is MyCustomControl)
{
((MyCustomControl)this.ActiveControl).Copy();
}
else if (this.ActiveControl is RichTextBox)
{
((RichTextBox)this.ActiveControl).Copy();
}
}
etc...
However, my controls are added to a SplitContainer, and debugging shows that this.ActiveControl is set to the splitcontainer instance, not the control, even though I know that control is selected.
So my last thought is to literally check if every control has focus:
public void menuEditCopy_Click(object sender, EventArgs e)
{
if (myCustomControl.Focused)
{
myCustomControl.Copy();
}
else if (richTextBox1.Focused)
{
richTextBox1.Copy();
}
}
I would like to avoid this if possible, it is a lot of controls, and if I add a new control, I would need to update it. Is there a better way of doing this?
Thanks
A SplitContainer implements ContainerControl, so you could check for either one and look for it's ActiveControl instead. ContainerControl is the base class, so I would go for that - you might catch another type of container as well:
private void DoCopy(Control control)
{
if(control is ContainerControl)
DoCopy(control.SelectedControl);
else if(control is MyCustomControl)
((MyCustomControl)control).Copy();
else if(control is RichTextBox)
((RichTextBox)control).Copy();
else
throw new NotSupportedException("The selected control can't copy!");
}
void menuEditCopy_Click(object sender, EventArgs e)
{
DoCopy(this.ActiveControl);
}
You could try settting the KeyPreview property of your form to true. Then you could set up a handler for the form's KeyDown event which would look like the following:
private void Form_KeyDown(object sender, KeyEventArgs e)
{
if(e.Modifiers == Keys.Control && e.KeyCode == Keys.C)
{
if (ActiveControl.GetType() == typeof(MyCustomControl))
{
((MyCustomControl)ActiveControl).Copy();
e.Handled = true;
}
}
}
Here you are specifying that you have handled the Ctrl-C event by setting the event args Handled property to true. Else, if you leave it as false, the Ctrl-C key press will be handled as per usual by each individual control.
Because we have set the KeyPreview to true the form's handler gets to see each key press before any other control that it contains and can decide to deal with the key press itself or else allow it to be handled in the same way as if the form had never previewed it.
I think as well it would be necessary to remove the short-cut key from your menu item (although you could still manually put the text "Ctrl+C" next to your menu item name) for this to work, otherwise your menu item will hijack the key stroke.