I want to add a simple (at least I thought it was) behaviour to my WPF TextBox
.
When the user presses Escape I want the TextBox
he is editi
The code I have been using :
// Move to a parent that can take focus
FrameworkElement parent = (FrameworkElement)textBox.Parent;
while (parent != null && parent is IInputElement && !((IInputElement)parent).Focusable)
{
parent = (FrameworkElement)parent.Parent;
}
DependencyObject scope = FocusManager.GetFocusScope(textBox);
FocusManager.SetFocusedElement(scope, parent as IInputElement);
in .NET Framework 4 just Keyboard.ClearFocus();
My answer does not adress the above question directly, however, I feel that the wording of it has caused it to become "The Question" about programmatically getting rid of focus. A common scenario where this is needed is for the user to be able to clear focus upon left-clicking the background of a root control, like window.
So, to achieve this, you can create an Attached Behavior that will switch focus to a dynamically created control (in my case, an empty label). It is preferrable to use this behavior on the highest-level elements like windows, as it iterates through it's children to find a panel it can add a dummy label to.
public class LoseFocusOnLeftClick : Behavior<FrameworkElement>
{
private readonly MouseBinding _leftClick;
private readonly Label _emptyControl = new Label() { Focusable = true, HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Top };
public LoseFocusOnLeftClick()
{
_leftClick = new MouseBinding(new RelayCommand(LoseFocus), new MouseGesture(MouseAction.LeftClick));
}
protected override void OnAttached()
{
AssociatedObject.InputBindings.Add(_leftClick);
AssociatedObject.Loaded += AssociatedObject_Loaded;
}
protected override void OnDetaching()
{
AssociatedObject.InputBindings.Remove(_leftClick);
AssociatedObject.Loaded -= AssociatedObject_Loaded;
}
private void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
{
AssociatedObject.Loaded -= AssociatedObject_Loaded;
AttachEmptyControl();
}
private void AttachEmptyControl()
{
DependencyObject currentElement = AssociatedObject;
while (!(currentElement is Panel))
{
currentElement = VisualTreeHelper.GetChild(currentElement, 0);
}
((Panel)currentElement).Children.Add(_emptyControl);
}
private void LoseFocus()
{
_emptyControl.Focus();
}
}