XAML - 如何使用 KeyBinding 命令转到文本框中的新行?

XAML - How can I use a KeyBinding command to go to a new line in the textbox?

我只是想在按下 Return + Shift 时换行。

我从之前的 post 那里得到了这么多:

<TextBox.InputBindings>
                <KeyBinding Key="Return" Modifiers="Shift" Command=" " />
</TextBox.InputBindings>

但我找不到任何地方解释如何在文本框中完成移动到新行。

我无法使用:AcceptsReturn="True" 因为我希望 return 触发按钮。

如果您没有定义 ICommand,您可以将 UIElement.PreviewKeyUp 事件的处理程序附加到 TextBox。否则,您将必须定义一个 ICommand 实现并将其分配给 KeyBinding.Command,以便 KeyBinding 可以实际执行。两种解决方案最终都执行相同的逻辑来添加换行符。

然后使用 TextBox.AppendText 方法附加一个换行符,并使用 TextBox.CaretIndex 属性 将插入符号移动到新行的末尾。

MainWindow.xaml

<Window>
  <TextBox PreviewKeyUp="TextBox_PreviewKeyUp" />
</Window>

MainWindow.xaml.cs

partial class MainWindow : Window
{
  private void TextBox_PreviewKeyUp(object sender, KeyEventArgs e)    
  {
    if (!e.Key.Equals(Key.Enter) 
      || !e.KeyboardDevice.Modifiers.HasFlag(ModifierKeys.Shift))
    {
      return;
    }

    var textBox = sender as TextBox;
    textBox.AppendText(Environment.NewLine);
    textBox.CaretIndex = textBox.Text.Length;
  }
}

我找到了一种不使用 ICommand 的好方法。

简单地将此 PreviewKeyDown 事件添加到 xaml 中的控件:

PreviewKeyDown="MessageText_PreviewKeyDown"

这是后面的 C#:

private void MessageText_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
    {
        // Get the textbox
        var textbox = sender as TextBox;

        // Check if we have pressed enter
        if (e.Key == Key.Enter && Keyboard.Modifiers.HasFlag(ModifierKeys.Shift))
        {
            // Add a new line where cursor is
            var index = textbox.CaretIndex;

            // Insert a new line
            textbox.Text = textbox.Text.Insert(index, Environment.NewLine);

            // Shift the caret forward to the newline
            textbox.CaretIndex = index + Environment.NewLine.Length;

            // Mark this key as handled by us
            e.Handled = true;
        }
    }