I have a TextBox that a user can type a search term into and a ListBox that displays results. There is also a button will display some information based on the item selected on click.
I'm trying to scroll through the listbox using the up and down arrow keys so the user doesn't have to click the item, then the button. At that point I might as well just rely on the double click event to do the work since they are already on the item. However, I'm trying to make this more "keyboard only friendly".
The following code works, but with one minor flaw:
private void txtSearchTerm_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Down && Results.SelectedIndex < (Results.Items.Count - 1))
{
Results.SelectedIndex++;
}
else if (e.KeyCode == Keys.Up && Results.SelectedIndex > 0)
{
Results.SelectedIndex--;
}
}
With this code, the cursor still moves left and right along with the selected item changing. I want it to remain where it is (not forcing it to the end). I didn't have any luck with the txtSearchTerm.Select(...) event, but I guess I could have missed something...
There is a TextChanged event, but it only calls to a search function I wrote that populates the list box as the user types, so I will leave that code out for simplicity.
Am I missing something or overlooking some method to make this TextBox/ListBox combo function how I'm intending?
Quick note: If you've ever used UltraEdit, I'm trying to mimic the behavior of that configuration window, basically.
You should use e.Handled = true; to cancel using the key that you processed:
private void txtSearchTerm_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Down)
{
if (Results.SelectedIndex < (Results.Items.Count - 1))
Results.SelectedIndex++;
e.Handled = true;
}
else if (e.KeyCode == Keys.Up)
{
if (Results.SelectedIndex > 0)
Results.SelectedIndex--;
e.Handled = true;
}
}
I set e.Handled = true; if the key is Keys.Down or Keys.Up regardless of the SelectedIndex to completely disable moving caret using those keys.
I have a pretty complex visual studio form where I have like 2 textboxes, and some other stuff I need for my project, but my problem is - I want to use arrow keys to do tasks (bind them like short-cuts) and I can do that only when I don't edit my textboxes or else I get stuck in them and even if I try to reset my cursor (click on the form) it stays in the textbox and I can only jump in between characters, not use my arrows like I binded them. So my two questions are -
How can I reset my cursor if I have previously selected a textbox?
How can I unbind my default arrow keys so they don't jump between characters and buttons?
Try adding a key event on the textboxes that catches the arrow key strokes and moves focus accordingly.
void inputField_KeyDown(object sender, KeyEventArgs e)
{
if ((e.KeyCode == Keys.Left) || (e.KeyCode == Keys.Right) || (e.KeyCode == Keys.Up) || (e.KeyCode == Keys.Down))
{
//nextControl.Focus();
}
}
Just be aware that this will then remove the ability to navigate between the characters in a textbox. I think that the numpad arrows might still work inside the textbox since they have a different keycodes, but I can't be sure right now.
Hi and Welcome to stackoverflow, I'm not sure i have a complete answere but I have a few thougth on the subject.
Hard to answeer without some code, to se how you turns off the curser i think?
why does it have to in the first place? seems to overcomlicate it abit ?
the way i whould go about this, it's to egnore the the muse curser all together at first, and make a on KeyDown event on the textbox that needs the to be able to shift to the next like this
private void yourControl_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == Keys.Down || e.KeyData == Keys.Up)
{
// shift to next textbox maybe, to keep thing simple ?
}
}
though this will act wierd if you use a mulitlines textbox or other control that allready have these keys bind.
you can allso add a field boolean as a switch to enable the keys, that gets set on the textsboxes activation (thats what happens then you click it to write text) and it can be reused, then it look like this
class yourProgram
{
private bool fieldIskeysMode = false;
private void yourControl_KeyDown(object sender, KeyEventArgs e)
{
if (fieldIskeysMode) // if True
{
if (e.KeyData == Keys.Down || e.KeyData == Keys.Up)
{
// shift to next textbox maybe, to keep thing simple ?
}
if (e.KeyData == Keys.Escape) fieldIskeysMode = false; // one line set to falls on esc key
}
}
private void yourControl_Activate(object sender, KeyEventArgs e)
{
if (!fieldIskeysMode) // if not true
{
fieldIskeysMode = true;
}
}
}
hope this helps.
I would like to add the functionality that is found in the command line prompt into my WPF TextBox. In the command propmpt when the user pushes the up arrow the previous command that was used will appear. And if he keeps pushing the up arrow the next previous text will be seen. And if the user pushes down then it will go the other way again.
What would be the best way to accomplish this? (The built in redo / undo works more on a document level than what I am requiring.)
You can use Undo e Redo Application Commands.
This is the MVVM not compliant version:
In your XAML
<TextBox Margin="5" PreviewKeyUp="TextBox_PreviewKeyUp" AcceptsReturn="False" />
In your code-behind
private List<string> _history = new List<string>();
private int _historyIndex = -1;
private void TextBox_PreviewKeyUp(object sender, KeyEventArgs e)
{
TextBox textBox = (TextBox)sender;
if (e.Key == Key.Return)
{
_history.Add(textBox.Text);
if (_historyIndex < 0 || _historyIndex == _history.Count - 2)
{
_historyIndex = _history.Count - 1;
}
textBox.Text = String.Empty;
return;
}
if (e.Key == Key.Up)
{
if (_historyIndex > 0)
{
_historyIndex--;
textBox.Text = _history[_historyIndex];
}
return;
}
if (e.Key == Key.Down)
{
if (_historyIndex < _history.Count - 1)
{
_historyIndex++;
textBox.Text = _history[_historyIndex];
}
return;
}
}
I hope this is the functionality you meant.
You could simply use the PreviewKeyDown event and check for Key.Down or Key.Up and read a List of your last commands. If you set e.Handled = true the cursor don't jump up.
private void TextBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Up)
{
e.Handled = true;
//Here comes the code where you read your last commands and print it to your Textbox
}
//Same for Key.Down
}
To make it MVVM-compliant you can use an eventtrigger which triggers a command in your Viewmodel.
Hope this gives you the idea. Unfortunately I haven't enough time to program for you. :)
You can persist commands into stack collection.
I have a very simple Windows Forms Application. And, in Windows (or, atleast Windows Forms Applications), when you press Enter while inside a Single-line TextBox Control, you hear a Ding. It's an unpleasent sound, that indicated you cannot enter a newline, because it is a single-line TextBox.
This is all fine. However, in my Form, I have 1 TextBox, and a Search Button. And I am allowing the user to Perform a search by pressing Enter after they've finished typing, so they don't have to use the mouse to click the Search Button.
But this Ding sound occurs. It's very annoying.
How can we make it so just that sound doesn't play at all in my Form?
#David H - Here's how I'm detecting the enter pressing:
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
// Perform search now.
}
}
It works for me:
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
//Se apertou o enter
if (e.KeyCode == Keys.Enter)
{
//enter key is down
this.doSomething();
e.Handled = true;
e.SuppressKeyPress = true;
}
}
The SuppressKeyPress is the really trick. I hope that help you.
Check out the Form.AcceptButton property. You can use it to specify a default button for a form, in this case for pressing enter.
From the docs:
This property enables you to designate
a default action to occur when the
user presses the ENTER key in your
application. The button assigned to
this property must be an
IButtonControl that is on the current
form or located within a container on
the current form.
There is also a CancelButton property for when the user presses escape.
Try
textBox.KeyPress += new KeyPressEventHandler(keypressed);
private void keypressed(Object o, KeyPressEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
e.Handled = true; //this line will do the trick
}
}
Just add e.SuppressKeyPress = true; in your "if" statement.
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
//If true, do not pass the key event to the underlying control.
e.SuppressKeyPress = true; //This will suppress the "ding" sound.*/
// Perform search now.
}
}
You can Use KeyPress instead of KeyUp or KeyDown its more efficient
and here's how to handle
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Enter)
{
e.Handled = true;
button1.PerformClick();
}
}
and say peace to the 'Ding'
Use SuppressKeyPress to stop continued processing of the keystroke after handling it.
public class EntryForm: Form
{
public EntryForm()
{
}
private void EntryTextBox_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Enter)
{
e.Handled = true;
e.SuppressKeyPress = true;
// do some stuff
}
else if(e.KeyCode == Keys.Escape)
{
e.Handled = true;
e.SuppressKeyPress = true;
// do some stuff
}
}
private void EntryTextBox_KeyUp(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Enter)
{
// do some stuff
}
else if(e.KeyCode == Keys.Escape)
{
// do some stuff
}
}
}
On WinForms the Enter key causes a Ding sound because the form property AcceptButton is not specified.
If you don't need an AcceptButton the ding sound can be suppressed by setting the form KeyPreview to true and enter the following KeyPress event:
private void Form_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == '\r')
e.Handled = true;
}
No matter what control is active, there will be no more ding sound when pressing the Enter key. Since the key event proccessing order is KeyDown, KeyPress and KeyUp the Enter key will still work for the KeyDown events for the controls.
I stumbled on this post while trying to handle a KeyDown this worked for me.
If e.KeyCode = Keys.Enter Then
e.SuppressKeyPress = True
btnLogIn.PerformClick()
End If
Supressing the Key Press stops the event from being sent to the underlying control. This should work if you're manually handling everything that the enter key will be doing within that textbox. Sorry about the Visual Basic.
$("#txtSomething").keypress(function (e) {
if (e.which == 13) {
e.Handled = true; //This will prevent the "ding" sound
//Write the rest of your code
}
});
There is a very little chance anyone gets to this answer but some other answers are truly scary. Suppressing event on KeyDown kills 2 additional events in one strike. Setting e.Handled property to true is useless in this context.
The best way is to set Form.AcceptButton property to the actual Search Button.
There is also another way of utilizing Enter key - some people may want it to act as TAB button. To do that, add a new Button, set its Location property outside of the Form area (i.e. (-100, -100)) - setting Visible property to false may disable Button handlers in some cases. Set Form.AcceptButton property to your new button. In Click event handler add following code
this.SelectNextControl(ActiveControl, true, true, true, true)
Now, you may want to transfer focus only when focus it on TextBox you may want to either test ActiveControl type or use e.Supress property in event handlers of controls not meant to use Enter as TAB
That's it. You don't even need to capture e.KeyCode
Set your Search button's IsDefault property to true. This will make it a default button and it will be auto-clicked when Enter is pressed.
Well I lived with this problem long enough and looked it up here.
After thinking about this for quite some time and wanting the simplest way to fix it I came up with the easiest but not so elegant way to fix it.
Here is what I did.
Put 2 invisible buttons "Ok" and "Cancel" on the form.
Set the AcceptButton and CancelButton Property on the form to the invisible buttons.
Added no code to the buttons!
This solved all the secondary problems listed in this thread including the ToolStripMenu. My biggest complaint was the BindingNavigator, when I would enter a record number into the Current position to navigate to and pressed enter.
As per the original question in which the programmer wanted a search function when the enter button was pressed I simply put the search code in the invisible OK Button!
So far this seems to solve all problems but as we all know with Visual Studio, something will probably crop up.
The only other possible elegant way I could think of would be to write a new keystroke handling class which is way to much work for most of my projects.
You can set your textbox multi-line to true then handle the Enter key press.
private void yourForm_Load(object sender, EventArgs e)
{
textBox1.Multiline = true;
}
//then write your TextBox codes
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
// doSomething();
}
}
i changed the textbox properties for an multiline textbox and it works for me.
Concerning the e.SuppressKeyPress = true; solution, it works fine by itself. Setting SuppressKeyPress to true also sets Handled to true, so there's no need to use e.Handled= true;
void RTextBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == Keys.Enter)
{
//do ...
bool temp = Multiline;
Multiline = true;
e.Handled = true;
Multiline = temp;
}
}
I want to always Focus on a specific TextBox on my WPF application whenever I click on anything on the application it should always focus on the TextBox.
Add to the TextBox.OnLostFocus event a handler which sets the focus to the TextBox.
There is an event handler MouseLeftMouseButton. When the event handler was triggered, use textbox.Focus() inside the handler.
If i'm right, your intention is to get the keyboard commands and display the char pressed into your textbox even if the focus is on other controls.
If that is the case, you can route the keyboard commands to the root control (control in the top level... eg: window), analyse them and display in the textbox. I'ld try to give examples if that helps.
EDIT:
private void Window_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
if (Keyboard.Modifiers != ModifierKeys.Shift)
{
if (e.Key > Key.A && e.Key < Key.Z)
{
textBox1.Text += e.Key.ToString().ToLower();
}
}
else
{
if (e.Key > Key.A && e.Key < Key.Z)
{
textBox1.Text += e.Key.ToString();
}
}
e.Handled = true;
}