4

I'd like to be able to modify the behaviour of the wpf textbox without the need of implementing a new class.

I want an Excel like enter / Alt+Enter behavior, when the user hits "Enter" the textbox is validated (movefocus ...), but when he hits "ALT+Enter", the textbox has to add a new line (my textbox supports multiline : AcceptsReturn is true).

I've tried (in the textbox PreviewKeyDown event): - Raising to construct a KeyEventArgs and a TextCompositionEventArgs following this link : How can I programmatically generate keypress events in C#? - I've tried SendKeys.SendWait("{ENTER}") but it sends many new line commands

Is there a way to do this ?

Thank you

    private void m_MeasurementName_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        var tb = (sender as TextBox);

        if (Keyboard.Modifiers == ModifierKeys.Alt && Keyboard.IsKeyDown(Key.Enter))
        {
            // 1st try
            var key = "\n\r";
            var routedEvent = Keyboard.KeyDownEvent;
            tb.RaiseEvent(new TextCompositionEventArgs(InputManager.Current.PrimaryKeyboardDevice, new TextComposition(InputManager.Current, tb, key)) { RoutedEvent = routedEvent });

            // 2nd
            var key = Key.Enter;
            var routedEvent = TextCompositionManager.TextInputEvent;
            tb.RaiseEvent(new KeyEventArgs(Keyboard.PrimaryDevice, PresentationSource.FromVisual(tb), 0, key) { RoutedEvent = routedEvent });

            // 3rd
            System.Windows.Forms.SendKeys.SendWait("{ENTER}");

            // 4th Strangely works but not ... you know
            MessageBox.Show("ALT+ENTER");

            e.Handled = true;
        }
        else if (Keyboard.IsKeyDown(Key.Enter))
        {
            tb.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
            e.Handled = true;
        }
    }
Community
  • 1
  • 1
Arslan
  • 569
  • 1
  • 4
  • 14

1 Answers1

7

If the user presses Alt+Enter, simply add a new line onto the existing TextBox.Text. If they hit just Enter, trigger an UpdateSource on the Text Binding

private void m_MeasurementName_PreviewKeyDown(object sender, KeyEventArgs e)
{
    var tb = (sender as TextBox);

    if (Keyboard.Modifiers == ModifierKeys.Alt && Keyboard.IsKeyDown(Key.Enter))
    {
        tb.Text += "\r\n";
        tb.SelectionStart = tb.Text.Length;

        e.Handled = true;
    }
    else if (Keyboard.IsKeyDown(Key.Enter))
    {
        var textBinding = BindingOperations.GetBindingExpression(
            tb, TextBox.TextProperty);

        if (textBinding != null)
            textBinding.UpdateSource();

        e.Handled = true;
    }
}

For the NewLine to work, make sure AcceptsReturn="True" on your TextBox

Rachel
  • 130,264
  • 66
  • 304
  • 490
  • It works but I feel so dumb now :( Btw the caret is at the first but I've fixed it by adding tb.SelectionStart = tb.Text.Length; after tb.Text += ..., and now the carret is at the last position – Arslan Nov 15 '11 at 16:43
  • @Arslan Don't worry, I'm sure everyone over-thinks problems at some point or another. Glad it works though, and I'll add your comment to my answer :) – Rachel Nov 15 '11 at 16:51