WPF如何在TextBox上管理ENTER命中以进行消息传递

时间:2015-06-09 12:17:58

标签: c# wpf textbox keydown

采用简单的消息传递程序,例如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 !
    }
}

发生以下情况:

  1. 使用CTRSHIFT,我可以在TextBox :)中创建新行;
  2. 我无法粘贴Clipboard中的多行文字:只会粘贴第一行,而不是其他内容:(;
  3. 如果我使用CTRL + V粘贴内容,MessageField_KeyDown事件会考虑CTRL点击,因此,如果我按ENTER,则不会发送消息但是会创建换行符:/(在您粘贴内容并立即发送的情况下);
  4. 如果我的光标位置在输入文本的结尾之前,CTR/SHIT + ENTER将在文本末尾创建换行符,而不管光标位置如何:/
  5. 那么,我该怎么调整这段代码呢?谢谢你的帮助!

1 个答案:

答案 0 :(得分:3)

解决方案的结果如下:

正常
Normal

一个SHIFT + ENTERenter image description here

当您按ENTER时,它在“正常”中看起来只有框中没有文字

如评论中所述,您可以将AcceptsReturnTextWrapping属性用于多行文本框(例如在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 KeyAcceptsReturn设置为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 = ""; } } 。因此,如果你按下回车键,你会看到一个换行而不是Send()如果你的程序是这样的:

PreviewKeyDown

所以你需要实现PreviewKeyDown eventhandler。因为在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; } } 事件处理程序中,事件通过(父)元素进行路由。 Look at this Answer

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

{{1}}

多行文字框的专业是您可以复制和粘贴的 +你对CTRL推或没有问题。

你怎么看?

希望有所帮助