How to move to next textbox form a multiline textbox - c#

I have this procedure wich moves the cursor to the next textbox up/down within non multiline textbox.
When using key down from multiline textbox, cursor moves to the next textbox but does not focus in the next textbox when pressing key up idem. With key enter it moves from multiline to the next textbox and focuses it.
What can be the reason ?
I have 8 textboxes which are groupped with tag properties from 0 to 7. TxtboxNbrLimit is set to 8
private void textBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter || e.KeyCode == Keys.Down)
{
if (KeyIndex < TxtboxNbrLimit)
++KeyIndex;
if (KeyIndex == TxtboxNbrLimit)
{
SaveBtn.Select();
return;
}
if (_textBox[KeyIndex].Text != "")
ChangeDone = true;
_textBox[KeyIndex].SelectionStart = 0;
_textBox[KeyIndex].SelectionLength = _textBox[KeyIndex].Text.Length;
_textBox[KeyIndex].Select();
_textBox[KeyIndex].Focus();
}
else
{
if (e.KeyCode == Keys.Up)
{
if (KeyIndex > 0)
--KeyIndex;
_textBox[KeyIndex].SelectionStart = 0;
_textBox[KeyIndex].SelectionLength = _textBox[KeyIndex].Text.Length;
_textBox[KeyIndex].Select();
_textBox[KeyIndex].Focus();
}
}
}

Try to move your logic to key up event instead of key down. That will work fine, TESTED.
Maybe multiline TextBox has some kind of event handler internally to handle up/down keyboard key pressed event, to move cursor between text lines. So your code work will be overridden by that internal behavior.
And in case you put it in key up event, the opposite happened. Your code logic will override effect of TextBox's internal behavior. So if the TextBox contains multiline text, the cursor will move to next/previous TextBox instead of moving between text lines inside the multiline TextBox.

Related

UWP textbox cursor functionality on down key

I have several Textboxes in a UWP project. If I press the down key inside a textbox, the cursor will jump to the end of the text; unless the cursor is at the very front. If the cursor is at the front of the text, pressing down does nothing. Is there a way to make the cursor jump to the end of the text upon a down key press even if the cursor is at the very front?
I made a new UWP project to test this and the above functionality is the default.
You can use SelectionStart and SelectionLength property in PreviewKeyDown Event
Note: e.Handled has to be set false
/*Xaml Code*/
<TextBox x:Name="SelectionTextBox" PreviewKeyDown="SelectionTextBox_PreviewKeyDown"/>
//C# code
private void SelectionTextBox_PreviewKeyDown(object sender, KeyRoutedEventArgs e)
{
if (e.Key == Windows.System.VirtualKey.Down)
{
SelectionTextBox.SelectionStart = SelectionTextBox.Text.Length - 1;
SelectionTextBox.SelectionLength = 0;
}
else
{
e.Handled = false;
}
}

WPF how to manage ENTER hit on TextBox for messaging purpose

Take a simple messaging program, such as Steam friend conversation.
When you hit ENTER, the message is sent, and the message field is emptied.
When you enter CTRL/SHIFT + ENTER a newline is created. If your cursor is not at the end of the input text, then all the text appearing after your cursor will be sent to a newline.
Well, how do you accomplish such a feat ?
Furthermore, I'd like to know how to have the aforementioned features and also how to still be able to paste a multiline text into the message field.
For now, this is my code. It's something but does not get all the job done :
private bool ctrlOrShift = false;
private void MessageField_KeyDown( object sender, KeyEventArgs e )
{
if( e.Key == Key.LeftCtrl || e.Key == Key.LeftShift )
{
ctrlOrShift = true;
}
else if( e.Key == Key.Enter && ctrlOrShift != true && !MessageField.AcceptsReturn )
{
AsyncSendMessage();
}
else if( e.Key == Key.Enter && ctrlOrShift != true && MessageField.AcceptsReturn )
{
MessageField.AcceptsReturn = false;
}
else if( e.Key == Key.Enter && ctrlOrShift == true )
{
ctrlOrShift = false;
MessageField.AcceptsReturn = true;
MessageField.Text += System.Environment.NewLine;
MessageField.Select( MessageField.Text.Length, 0 );
MessageField.AcceptsReturn = false;
}
else
{
ctrlOrShift = false; // Canceled because follow-up key wat not ENTER !
}
}
The following scenarios occur :
Using CTR or SHIFT, I can create a new line in my TextBox :) ;
I cannot paste a multiline text from the Clipboard: only the first line will be pasted, nothing else :( ;
If I use CTRL + V to paste content, the MessageField_KeyDown event takes the CTRL hit is taken into account, therefore, if I press ENTER, message is not sent but a newline is created instead :/ (in a case where you would paste a content and send it right away) ;
If my cursor position is before the end of the input text, CTR/SHIT + ENTER will create a newline at the end of the text regardless of the cursor position :/
So, how can I tweak this code ? Thanks for the help !
The Result of the Solution is this:
Normal
After one SHIFT + ENTER
When you push ENTER it looks like in Normal only without text in the box
As mentioned in the comments you could use the AcceptsReturn and TextWrapping properties for a multiline textbox (like in steam).
Use Height = Auto for a better looking one (otherwise you only have one line and all other lines disappear)
XAML
for Textbox:
<TextBox HorizontalAlignment="Left" Height="Auto" Margin="10,10,0,0"
TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top"
Width="497" AcceptsReturn="True"
KeyDown="TextBoxKeyDown" PreviewKeyDown="TextBoxPreviewKeyDown"/>
Event Handler:
This is not that easy as i thought first :'D But i figured it out.
When you use the AcceptsReturn Property the Enter Key is Handeled by the AcceptsReturn. So if you push enter you will see a new line instead of a Send() if you programm is like this:
private void TextBoxKeyDown(object sender, KeyEventArgs e)
{
var textbox = sender as TextBox;
// This will never happen because the Enter Key is handeled before
// That means TextBoxKeyDown is not triggered for the Enter key
if (e.Key == Key.Enter &&
!(Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)) &&
!(Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.LeftShift)))
{
// Send(textBox.Text)
textbox.Text = "";
}
}
So you need to implement the PreviewKeyDown eventhandler. Because in the PreviewKeyDown event handler the Event is routed through the (Parent)Elements.
Look at this Answer
Also note the e.Handled = true line. Otherwise the Enter is routed through the method to the AcceptsReturn and you will have 2 lines after the enter, but the Textbox is empty.
With this method the KeyDown Method is no longer needed!
private void TextBoxPreviewKeyDown(object sender, KeyEventArgs e)
{
// Enter key is routed and the PreviewKeyDown is also fired with the
// Enter key
var textbox = sender as TextBox;
// You don't want to clear the box when CTRL and/or SHIFT is down
if (e.Key == Key.Enter &&
!(Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)) &&
!(Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift)))
{
textbox.Text = "";
e.Handled = true;
}
}
The pros of the Multiline Textbox is that you can copy and paste
+ you have no problems with CTRL pushed or not.
What do you think about it?
Hope it helps

control what the enter key does in WPF

I have a RichTextBox that i am searching text in and I want to be able to control what the enter key does when text is selected. I am able to use this if test below to call the method that I want, but my issue is after the method gets hit when the enter key is pressed it then moves the text to the second line and I want to be able to stop this from happening when the text is highlighted.
I test to check if the text is selected when enter is pressed.
if (IsTextSelected == true)
{
btnSearch_Click(sender, null);
}
You can listen to the PreviewKeyDown event like:
<RichTextBox PreviewKeyDown="RichTextBox_PreviewKeyDown"/>
and in the handler:
private void RichTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Return)
{
// DO YOUR WORK HERE and then set e.Handled to true on condition if you want to stop going to next line//
e.Handled = true;
}
}

How to change the focus inside a form and make the new control deal with the key pressed?

I have a form with a search box and a datagridview with the results.
What I need is the search box to always get the focus whenever I press a char or number key, and then process the key. So, for instance, if my focus is on the datagrid, and I press a char, it'll go to the search box. (Additionally, whenever the Up or Down arrows are pressed in the form, the focus will go to the datagrid, but I got no problem with that.)
Now, the code below will work as a charm for chars. When I get to the numbers, though, I can't do it the same way (as my e.KeyCode.ToString() will not give me the number, but a "d0" or "numpad0").
private void Form_KeyDown(object sender, KeyEventArgs e)
{
if (!this.tbxSearch.Focused)
{
if ((e.KeyCode >= Keys.A) && (e.KeyCode <= Keys.Z))
{
this.tbxSearch.Focus();
this.tbxSearch.Text = (e.Shift) ? e.KeyCode.ToString() : e.KeyCode.ToString().ToLower();
this.tbxSearch.SelectionStart = this.tbxSearch.Text.Length;
}
}
}
Of course, I might do it just about the same way, and simply get the last char in the "e.KeyCode.ToString()", but it doesn't seem alright to me. I mean, there must be a simpler way of just changing the focus and then making the control deal with the key pressed.
I've tried making it in the PreviewKeyDown event, but it won't be triggered by the form (even with the KeyPreview property set to true):
private void Form_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if ((e.KeyCode == Keys.Down) || (e.KeyCode == Keys.Up))
this.dgvResults.Focus();
else
this.tbxSearch.Focus();
}
So I was left wondering: how can I change the focus on a form and let the new control deal with the key?
You can check if a key is a digit like this:
private Keys[] numericKeys =
{
Keys.D1,
Keys.D2,
Keys.D3,
Keys.D4,
Keys.D5,
Keys.D6,
Keys.D7,
Keys.D8,
Keys.D9,
Keys.D0,
Keys.NumPad0,
Keys.NumPad1,
Keys.NumPad2,
Keys.NumPad3,
Keys.NumPad4,
Keys.NumPad5,
Keys.NumPad6,
Keys.NumPad7,
Keys.NumPad8,
Keys.NumPad9
};
...
bool isDigit = numericKeys.Contains(e.KeyCode);
or like this:
bool isDigit = Char.IsDigit((char)e.KeyCode);
or:
bool isLetterOrDigit = char.IsDigit((char)e.KeyCode);

c# Listbox control (arrows and enter keys)

I have a listbox which displays the contents of an array. The array is populated with a list of results when my "go" button is pressed.
The go button is set as the AcceptButton on the form properties so pressing the Enter key anywhere in the focus of the form re-runs the go button process.
Double clicking on a result from the array within the listbox works fine using below:
void ListBox1_DoubleClick(object sender, EventArgs e) {}
I would like to be able to use my arrow keys and enter keys to select and run an event without having to double click on the line within the listbox. (however go button runs each time instead)
Basically open the form, type search string, press enter to run go button, use up and down arrows then press enter on selection to run same event as double click above. Will need to change focus after each bit.
You can handle the KeyDown events for the controls you want to override. For example,
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
//execute go button method
GoButtonMethod();
//or if it's an event handler (should be a method)
GoButton_Click(null,null);
}
}
That will perform the search. You can then focus your listbox
myListBox.Focus();
//you might need to select one value to allow arrow keys
myListBox.SelectedIndex = 0;
You can handle the Enter button in the ListBox the same way as the TextBox above and call the DoubleClick event.
This problem is similar to -
Pressing Enter Key will Add the Selected Item From ListBox to RichTextBox
Certain controls do not recognize some keys when they are pressed in Control::KeyDown event. For e.g. list box does not recognize if the key pressed is Enter key.
See the remarks section of the Control::KeyDown event reference.
One way to resolve your problem might be writing a method for the Control::PreviewKeyDown event for your list box control:
private void listBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Up && this.listBox1.SelectedIndex - 1 > -1)
{
//listBox1.SelectedIndex--;
}
if (e.KeyCode == Keys.Down && this.listBox1.SelectedIndex + 1 < this.listBox1.Items.Count)
{
//listBox1.SelectedIndex++;
}
if (e.KeyCode == Keys.Enter)
{
//Do your task here :)
}
}
private void listBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Enter:
e.IsInputKey = true;
break;
}
}

Categories

Resources