当用户在带有 AcceptsReturn = "True" 的 UWP 文本框中按下 CTRL+ENTER 键时如何避免换行

How to avoid newline when user presses CTRL+ENTER keys in a UWP TextBox with AcceptsReturn = "True"

我正在开发一个文本编辑 UwP 桌面应用程序,它需要在用户按下 ENTER 时添加一行,并在用户按下 CTRL + ENTER 时执行另一个过程。问题是删除在第二种情况下也创建的新行。如何防止这种情况发生?

    KeyEventHandler keyeventHandler = new KeyEventHandler(rtbText_KeyDown);

    rtbText.AddHandler(TextBox.KeyDownEvent, keyeventHandler, true);

    private static bool IsCtrlKeyPressed()
    {
        var ctrlState = CoreWindow.GetForCurrentThread().GetKeyState(VirtualKey.Control);
        return (ctrlState & CoreVirtualKeyStates.Down) == CoreVirtualKeyStates.Down;
    }

    private void rtbText_KeyDown(object sender, KeyRoutedEventArgs e)
    {
        if (IsCtrlKeyPressed())
        {
            switch (e.Key)
            {
                case VirtualKey.Enter: 
                    NviNew_Tapped(nviNew, null);
                    e.Handled = true; 
                    break;
            }
        }
    }

您可以使用 PreviewKeyDown 事件,因为 keydown 系统处理的键不会触发事件

    private void TextBox_PreviewKeyDown(object sender, KeyRoutedEventArgs e)
    {
        if (Window.Current.CoreWindow.GetKeyState(VirtualKey.Control).HasFlag(CoreVirtualKeyStates.Down)&& e.Key == Windows.System.VirtualKey.Enter)
        {
            e.Handled = false;
        }
    }

正如@Vignesh 所说,您可以使用 PreviewKeyDown 事件而不是 keydown 事件,并将事件设置为 "handled" 就像 e.Handled = true 以防止添加新的行。

KeyEventHandler keyeventHandler = new KeyEventHandler(rtbText_KeyDown);
rtbText.AddHandler(TextBox.PreviewKeyDownEvent, keyeventHandler, true);

或者基于此 document,您可以通过覆盖 Control.OnKeyDown 来更改文本框对键输入的反应方式。首先,声明一个自定义 class 继承自 TextBox 并覆盖 OnKeyDown 事件。然后就可以继续使用keydown事件做点什么了。

public class MyTextBox : TextBox
{
    protected override void OnKeyDown(KeyRoutedEventArgs e)
    {
        if (Window.Current.CoreWindow.GetKeyState(VirtualKey.Control).HasFlag(CoreVirtualKeyStates.Down) && e.Key == VirtualKey.Enter)
        {
            e.Handled = true;
        }
        else
        {
            base.OnKeyDown(e);
        }
    }
}

.xaml:

<local:MyTextBox Width="400" AcceptsReturn="True" x:Name="rtbText"></local:MyTextBox>