以一个简单的消息程序为例,例如 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
粘贴内容,MessageField_KeyDown
事件会考虑CTRL
命中,因此,如果我按ENTER
,不会发送消息,而是创建换行符:/(在您粘贴内容并立即发送的情况下); - 如果我的光标位置在输入文本结束之前,
CTR/SHIT + ENTER
将在文本末尾创建一个换行符,而不管光标位置如何:/
那么,我该如何调整这段代码呢?感谢您的帮助!
最佳答案
解决方案的结果是这样的:
正常
在一个SHIFT + ENTER
之后
当您按下 ENTER
时,它看起来像在 Normal 中,只有框中没有文本
如评论中所述,您可以为多行文本框(如在 Steam 中)使用 AcceptsReturn
和 TextWrapping
属性。
使用 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 Key
由 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
事件处理程序中,事件通过(父)元素进行路由。
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# - WPF 如何管理 ENTER 命中 TextBox 以进行消息传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30731856/