在UWP中将SHIFT + ENTER用于多行文本框

时间:2018-12-11 18:42:05

标签: c# uwp textbox keyboard

我想调整TextBox的行为,以便键盘上的SHIFT + ENTER插入新行,而ENTER仅执行另一条命令(例如,更改焦点或按下“发送”消息传递应用程序。)

默认情况下,将AcceptsReturn的{​​{1}}属性设置为TextBox时,按ENTER键会插入新行。将true更改为AcceptsReturn似乎根本无法使用新行,即使我手动添加新行也是如此:

false

基于this post,我能够提出一种在功能上可行但具有视觉副作用的变通方法。我将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,然后在按下时手动删除新行,然后在只按ENTER时执行我想要的代码。副作用是该文本框会扩展以容纳新行,然后立即再次收缩,这表明该文本框甚至在我的处理程序运行之前就自动处理了ENTER输入。此代码如下:

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 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); } } } 的值,但是没有用(如果默认行为在我的代码之前运行,这是有道理的。)

2 个答案:

答案 0 :(得分:1)

处理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);
        }
    }
}

答案 1 :(得分:1)

(在评论中继续)您可以使用 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;
            }
        }