/// <summary> /// Sends key strokes to the provided viewmodel. /// If the input would cause the intellisense window to /// trigger, the intellisense callback is invoked. /// </summary> /// <param name="keyStrokes">A FormattableString (not a string!) that contains keystrokes</param> /// <param name="vm">window view model</param> /// <param name="intellisenseCallback"></param> /// <returns></returns> private async Task TypeInput(FormattableString keyStrokes, WindowViewModel vm, TriggerIntellisense intellisenseCallback = null) { var device = new MockKeyboardDevice(InputManager.Current); ModifierKeys modifier = ModifierKeys.None; foreach (var stroke in ConvertToKeys(keyStrokes)) { var currentLine = vm.Entries[vm.FocusIndex]; // set up document state; in the real app this is done by databinding if (currentLine.Document is null) { var editor = new TextEditor { Document = new TextDocument() }; currentLine.Document ??= editor.Document; currentLine.SetEditor(editor); currentLine.TriggerIntellisense ??= intellisenseCallback ?? ((items) => { }); } // convert to input to the appropriate key press Key key; switch (stroke) { case char ch: // type the character into the editor and set up the key event currentLine.Document.Text += ch; currentLine.CaretOffset = currentLine.Document.Text.Length; key = CharToKey.ContainsKey(ch) ? CharToKey[ch] : (Key)keyConverter.ConvertFromString(ch.ToString()); break; case Key k: key = k; break; case ModifierKeys mod: modifier |= mod; continue; default: throw new InvalidOperationException("Unhandled type: " + stroke.GetType()); } device.ModifierKeysImpl = modifier; var keyDown = device.CreateKeyEventArgs(key, Keyboard.KeyDownEvent); await viewModelService.HandleKeyDown(vm, currentLine, keyDown); var keyUp = device.CreateKeyEventArgs(key, Keyboard.KeyUpEvent); await viewModelService.HandleKeyUp(vm, currentLine, keyUp); modifier = ModifierKeys.None; } }
private async Task TypeInput(string input, WindowViewModel vm, TriggerIntellisense callback = null) { var keyboard = Keyboard.PrimaryDevice; var source = Substitute.For <PresentationSource>(); foreach (var character in ConvertToKeys(input)) { var currentLine = vm.Entries[vm.FocusIndex]; if (currentLine.Document is null) { // this would normally be done by databinding var editor = new TextEditor { Document = new TextDocument() }; currentLine.Document ??= editor.Document; currentLine.SetEditor(editor); currentLine.TriggerIntellisense ??= callback ?? ((items, onClose) => { }); } // convert a character like '.' to OemPeriod Key key = CharToKey.ContainsKey(character) ? CharToKey[character] : (Key)keyConverter.ConvertFromString(character); // type the key if (!NoOutputKeys.Contains(key)) { currentLine.Document.Text += character; } currentLine.CaretOffset = currentLine.Document.Text.Length; var keyDown = new KeyEventArgs(keyboard, source, 0, key) { RoutedEvent = Keyboard.KeyDownEvent }; await viewModelService.HandleKeyDown(vm, currentLine, keyDown); var keyUp = new KeyEventArgs(keyboard, source, 0, key) { RoutedEvent = Keyboard.KeyUpEvent }; await viewModelService.HandleKeyUp(vm, currentLine, keyUp); } }
private async void TextEditor_PreviewKeyDown(TextEditor lineEditor, KeyEventArgs e) { await viewModelService.HandleKeyDown(Model, lineEditor.ViewModel(), e); }