WPF how to control Enter pressing on TextBox for messaging purposes
Take a simple messaging program like Chatting with Friends on Steam.
When pressed, the ENTER
message is sent and the message field is released .
As you type CTRL/SHIFT + ENTER
, a new line is created . If your cursor is not at the end of the input text , then all text that appears after your cursor will be sent to a new line .
Well, how do you achieve such a feat?
Also, I would like to know how to have the above mentioned functionality as well as how else it is possible to insert multi-line text in the message field.
So far, this is my code. This is something, but doesn't do all the work:
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 are possible:
- Using
CTR
orSHIFT
, I can create a new line in mineTextBox
:); - I can't insert multiline text from
Clipboard
: only the first line will be inserted, nothing else :(; - If I use
CTRL + V
to insert content, the eventMessageField_KeyDown
takes a hitCTRL
, so if I clickENTER
, the message is not sent, but a new line is created instead: / (in the case where you insert content and send it right away); - If my cursor position is before the end of the input text
CTR/SHIT + ENTER
will create a new line at the end of the text regardless of the cursor position: /
So how can I customize this code? Thanks for the help!
source to share
The result of the decision is the following:
Normal
After one SHIFT + ENTER
When you click ENTER
it looks like normal, only without text in the field
As mentioned in the comments, you can use the properties AcceptsReturn
and TextWrapping
for a multiline text field (for example, in the pair). Use Height = Auto
for better search (otherwise you will only have one line and all other lines will disappear) the
XAML
for the 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:
It's not as easy as I thought at first: "D But I figured it out.
When you use a property AcceptsReturn
, it Enter Key
gets highlighted AcceptsReturn
. So if you hit enter, you see a new line instead of Send () if you run the following command:
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 an event handler PreviewKeyDown
. Because in the event handler, the PreviewKeyDown
event is dispatched through the (parent) elements.
Look at this answer
Also notice the line e.Handled = true. Otherwise, Enter will be redirected through the AcceptsReturn method and after typing you will have 2 lines, but the text box 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 multi-line text box is that you can copy and paste + you have no problem pressing CTRL or not.
What do you think about this?
Hope it helps
source to share