在 UWP 中对多行文本框使用 SHIFT + ENTER
Use SHIFT + ENTER for multiline textbox in UWP
我想调整 TextBox
的行为,以便键盘上的 SHIFT + ENTER 插入一个新行,而只是 ENTER 执行不同的命令(例如更改焦点或按 "send" 就像在消息传递应用程序中一样)。
默认情况下,TextBox
的 AcceptsReturn
属性 设置为 true
时会在按下 ENTER 时插入一个新行。将 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);
}
}
}
基于 this post,我想出了一个功能可行但有视觉副作用的解决方法。我将 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
值,但这没有用(这是有道理的,如果默认行为是 运行ning 在我的代码之前)。
处理 PreviewKeyDown 事件,并将该事件标记为 "handled" 可防止首先添加新行(因此也可防止副作用)。完整的工作代码如下:
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);
}
}
}
(接续评论)您可以使用 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;
}
}
我想调整 TextBox
的行为,以便键盘上的 SHIFT + ENTER 插入一个新行,而只是 ENTER 执行不同的命令(例如更改焦点或按 "send" 就像在消息传递应用程序中一样)。
默认情况下,TextBox
的 AcceptsReturn
属性 设置为 true
时会在按下 ENTER 时插入一个新行。将 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);
}
}
}
基于 this post,我想出了一个功能可行但有视觉副作用的解决方法。我将 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
值,但这没有用(这是有道理的,如果默认行为是 运行ning 在我的代码之前)。
处理 PreviewKeyDown 事件,并将该事件标记为 "handled" 可防止首先添加新行(因此也可防止副作用)。完整的工作代码如下:
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);
}
}
}
(接续评论)您可以使用 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;
}
}