c#-WPF如何管理TextBox上的Enter命中消息

使用简单的消息传递程序,例如Steam朋友对话.

当您按ENTER键时,将发送消息,并且消息字段为空.

当您输入CTRL / SHIFT ENTER时,将创建一个换行符.如果光标不在输入文本的末尾,则光标之后出现的所有文本将被发送到换行符.

好吧,您如何完成这项壮举?

此外,我想知道如何具有上述功能,以及如何仍然能够将多行文本粘贴到消息字段中.

现在,这是我的代码.有点,但是不能完成所有工作:

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

发生以下情况:

>使用CTR或SHIFT,我可以在TextBox中创建新行:);
>我无法从剪贴板粘贴多行文本:仅粘贴第一行,其他内容:(;
>如果我使用CTRL V粘贴内容,则考虑到了CTRL命中的MessageField_KeyDown事件,因此,如果我按ENTER,则不发送消息,而是创建换行符:/(在粘贴a的情况下内容并立即发送);
>如果我的光标位置在输入文本的末尾之前,则CTR / SHIT ENTER将在文本末尾创建一个换行符,而不考虑光标位置:/

那么,如何调整此代码?谢谢您的帮助 !

解决方法:

解决方案的结果是这样的:

正常

一键切换后

当您按ENTER键时,它看起来像是在Normal中,但框中没有文本

如注释中所述,您可以对多行​​文本框使用AcceptsReturn和TextWrapping属性(例如在Steam中).
使用Height = Auto以获得更好的外观(否则您只有一条线而所有其他线都消失了)
XAML
对于文本框:

<TextBox HorizontalAlignment="Left" Height="Auto" Margin="10,10,0,0" 
     TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" 
     Width="497" AcceptsReturn="True" 
     KeyDown="TextBoxKeyDown" PreviewKeyDown="TextBoxPreviewKeyDown"/>

事件处理程序:
这并不是我首先想到的那么容易:’D但是我想通了.
当您使用AcceptsReturn属性时,Enter键由AcceptsReturn处理.因此,如果您按如下所示编程,则按回车键将看到一个新行,而不是一个Send():

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 = "";
    }
}

因此,您需要实现PreviewKeyDown事件处理程序.因为在PreviewKeyDown事件处理程序中,事件是通过(Parent)Elements路由的.
Look at this Answer

还要注意e.Handled = true行.否则,Enter将通过该方法路由到AcceptsReturn,在输入之后您将有2行,但是文本框为空.
使用此方法,不再需要KeyDown方法!

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;
    }
}

多行文本框的优点是您可以复制和粘贴
  CTRL按下与否都没有问题.

你怎么看待这件事?

希望能帮助到你

上一篇:C#:使用不同的键同时移动两个矩形


下一篇:Kubernetes:更新与回滚