1

In my WPF MVVM application I want to be able to undo changes to individual TextBox elements using the Esc key. I've set up a command for this and I want to trigger it through XAML thus:

<Window.InputBindings>
    <KeyBinding Command="{Binding EscKeyCommand}" CommandParameter="{Binding FocusManager.FocusedElement}"  Gesture="ESC" />
</Window.InputBindings>

The idea is that the CommandParameter passes the ElementName of the currently focussed TextBox (if indeed that's what's in focus) and the appropriate undo can then be handled within the ViewModel. I've tried a number of options for the CommandParameter including the one above but they all return null. So,

Question

How can I pass the currently focused element name through a CommandParameter?

ifinlay
  • 621
  • 1
  • 7
  • 24
  • It doesn't answer the question I've specifically posed but I've just realised that I can determine the focused element name in the command using Keyboard.FocusedElement. No need therefore to pass any CommandParameter. – ifinlay Dec 02 '18 at 16:03
  • As a user, I'd be surprised if ESC was "Undo". Ctrl-Z is "undo". – Daniel Mann Dec 02 '18 at 16:12
  • Indeed, but I have surprising users ;-) – ifinlay Dec 02 '18 at 16:16

2 Answers2

2

I am glad that you have already noticed KeyBoard.FocusedElment. But there still an answer for the question. Since FocusManager.FocusedElement is an attached property, the right way to bind it should be:

CommandParameter="{Binding (FocusManager.FocusedElement), ElementName='name of the window'}"
Alex.Wei
  • 1,798
  • 6
  • 12
  • Great this works perfectly as does the @AselaLiyanage answer. So which should I go for? Staying with the MVVM / decoupling mindset I think this one because the Command then just takes action on "an element from somewhere". Using Keyboard.FocusedElement within the command feels more like a conversation with the UI. Probably splitting hairs here mind you. Thanks to both for your contributions. – ifinlay Dec 04 '18 at 13:29
2

FocusManager gives the element with the logical focus. To use FocusManager.FocusedElement the scope needs to provided, in this case the window (this)

IInputElement focusedControl = FocusManager.GetFocusedElement(this);

But In your case since it is a text box that you need the focus of use Keyboard.FocusedElement.

In the view model when you execute EscKeyCommand get the element that has the keyboard focus with the following syntax and clear the text.

UIElement elementWithFocus = Keyboard.FocusedElement as UIElement;