private void SimulateKeyStrokesHasChanged(bool saveCurrentState) { var newStateKey = keyStateService.SimulateKeyStrokes; var currentStateKey = !newStateKey; if (saveCurrentState) { //Save old state values var lastState = new KeyboardOutputServiceState( currentStateKey, () => text, s => Text = s, //Set property (not field) to trigger bindings () => lastTextChange, s => lastTextChange = s, () => lastTextChangeWasSuggestion, b => lastTextChangeWasSuggestion = b, () => suppressNextAutoSpace, b => suppressNextAutoSpace = b, () => shiftStateSetAutomatically, b => shiftStateSetAutomatically = b, () => suggestionService.Suggestions, s => suggestionService.Suggestions = s); if (state.ContainsKey(currentStateKey)) { state[currentStateKey] = lastState; } else { state.Add(currentStateKey, lastState); } } //Restore state or default state if (state.ContainsKey(newStateKey)) { state[newStateKey].RestoreState(); } else { Log.InfoFormat("No stored KeyboardOutputService state to restore for SimulateKeyStrokes={0} - defaulting state.", newStateKey); Text = null; StoreLastTextChange(null); ClearSuggestions(); ReleaseUnlockedKeys(); AutoPressShiftIfAppropriate(); Log.Debug("Suppressing next auto space."); suppressNextAutoSpace = true; } //Release all down keys publishService.ReleaseAllDownKeys(); if (keyStateService.SimulateKeyStrokes) { //SimulatingKeyStrokes is on so publish key down events for all down/locked down keys KeyValues.KeysWhichCanBePressedOrLockedDown .Where(key => keyStateService.KeyDownStates[key].Value.IsDownOrLockedDown() && key.FunctionKey != null) .Select(key => key.FunctionKey.Value.ToVirtualKeyCode()) .Where(virtualKeyCode => virtualKeyCode != null) .ToList() .ForEach(virtualKeyCode => publishService.KeyDown(virtualKeyCode.Value)); } }