对UWP中的多行文本框使用SHIFT+ENTER



我想调整TextBox的行为,使键盘上的SHIFT+ENTER插入一行新行,而只是ENTER执行不同的命令(例如更改焦点或像在消息应用程序中那样按"send"(。

默认情况下,当按下ENTER键时,设置为trueTextBoxAcceptsReturn属性将插入新行。将AcceptsReturn更改为false似乎会阻止新行工作,即使我手动添加新行:

private void ContentTextBox_KeyUp(object sender, KeyRoutedEventArgs e)
{
// NOTE - AcceptsReturn is set to false in XAML.
if (e.Key == VirtualKey.Enter)
{
var keyState = CoreWindow.GetForCurrentThread().GetKeyState(VirtualKey.Shift);
if ((keyState & CoreVirtualKeyStates.Down) == CoreVirtualKeyStates.Down)
{
// SHIFT is pressed, so add a new line.
this.ContentTextBox.Text += "r";
}
else
{
// SHIFT is not pressed, so execute my ENTER logic.
this.Focus(FocusState.Programmatic);
}
}
}

基于这篇文章,我想出了一个功能上可行但有视觉副作用的解决方法。我将AcceptsReturn设置为true,然后在按下SHIFT时手动删除新行,然后在只按下ENTER时执行我想要的代码。副作用是,文本框会展开以容纳新行,然后立即再次收缩,这表明它会在运行我的处理程序之前自动处理ENTER输入。其代码如下:

private void ContentTextBox_KeyUp(object sender, KeyRoutedEventArgs e)
{
// NOTE - AcceptsReturn is set to true in XAML.
if (e.Key == VirtualKey.Enter)
{
// If SHIFT is pressed, this next IF is skipped over, so the
//     default behavior of "AcceptsReturn" is used.
var keyState = CoreWindow.GetForCurrentThread().GetKeyState(VirtualKey.Shift);
if ((keyState & CoreVirtualKeyStates.Down) != CoreVirtualKeyStates.Down)
{
// SHIFT is not pressed, so remove the new line.
string textboxText = this.ContentTextBox.Text;
textboxText = textboxText.Remove(textboxText.Length - 1);
this.ContentTextBox.Text = textboxText;
// Execute my ENTER logic.
this.Focus(FocusState.Programmatic);
}
}
}

有没有不同的方法可以做到这一点,或者消除副作用的方法?我尝试调整e.IsHandled值,但没有成功(如果默认行为在我的代码之前运行,这是有道理的(。

(继续注释(您可以使用PreviewKeyDown事件,因为系统处理的密钥不会触发keydown事件

private void TextBox_PreviewKeyDown(object sender, KeyRoutedEventArgs e)
{
if (Window.Current.CoreWindow.GetKeyState(VirtualKey.Shift).HasFlag(CoreVirtualKeyStates.Down)&& e.Key == Windows.System.VirtualKey.Enter)
{
//Add New Line
}
else if (e.Key == Windows.System.VirtualKey.Enter)
{
//This will prevent system from adding new line
e.Handled = true;
}
else
{
e.Handled = false;
}
}

处理PreviewKeyDown事件,并将该事件标记为"已处理",可以从一开始就防止添加新行(因此也可以防止副作用(。完整的工作代码如下:

private void ContentTextBox_PreviewKeyDown(object sender, KeyRoutedEventArgs e)
{
// NOTE - AcceptsReturn is set to true in XAML.
if (e.Key == VirtualKey.Enter)
{
// If SHIFT is pressed, this next IF is skipped over, so the
//     default behavior of "AcceptsReturn" is used.
var keyState = CoreWindow.GetForCurrentThread().GetKeyState(VirtualKey.Shift);
if ((keyState & CoreVirtualKeyStates.Down) != CoreVirtualKeyStates.Down)
{
// Mark the event as handled, so the default behavior of 
//    "AcceptsReturn" is not used.
e.Handled = true;
}
}
}
private void ContentTextBox_KeyUp(object sender, KeyRoutedEventArgs e)
{
// NOTE - AcceptsReturn is set to true in XAML.
if (e.Key == VirtualKey.Enter)
{
// If SHIFT is pressed, this next IF is skipped over, so the
//     default behavior of "AcceptsReturn" is used.
var keyState = CoreWindow.GetForCurrentThread().GetKeyState(VirtualKey.Shift);
if ((keyState & CoreVirtualKeyStates.Down) != CoreVirtualKeyStates.Down)
{
// SHIFT is not pressed, so execute my ENTER logic.
this.Focus(FocusState.Programmatic);
}
}
}

最新更新