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

    or SHIFT

    , I can create a new line in mine TextBox

    :);
  • 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 event MessageField_KeyDown

    takes a hit CTRL

    , so if I click ENTER

    , 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!

+3


source to share


1 answer


The result of the decision is the following:

Normal
Normal

After one SHIFT + ENTER


enter image description here

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

+3


source







All Articles