Я хочу добавить простое (по крайней мере, я так думал) поведение в свой WPF TextBox
.
Когда пользователь нажимает Escape, я хочу, чтобы TextBox
он редактировал текст, который был, когда пользователь начал редактирование, И я хочу убрать фокус с TextBox
.
У меня нет проблем с установкой текста для значения, которое он имел в начале редактирования.
Проблема в том, чтобы убрать фокус элемента. Я не хочу перемещать фокус на какой-либо другой компонент, я просто хочу, TextBox
чтобы он потерял фокус. Должен ли я иметь невидимый элемент, чтобы установить фокус, чтобы я TextBox
мог потерять фокус?
Keyboard.ClearFocus()
код программной части после щелчка где-то.ClearFocus
заставляетGotFocus
не срабатывать для недавно сфокусированного элемента управления, пока он все еще срабатывает для других элементов управления. Например, это большая проблема для моей пользовательской экранной клавиатуры. Это вызывает исчезновение каретки, что, вероятно, и есть все, что влечет за собой «фокус клавиатуры». Может меня больше интересует что-то вроде «фокус мыши».other.Focus()
.GotFocus
событие). В вашей программе всегда есть что-то с логической направленностью. Либо используйтеLostKeyboardFocus
событие, либо переместите фокус на другой элемент (который смещает логический фокус вместе с ним) перед очисткой фокуса клавиатуры.Код, который я использовал:
// 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);
источник
Немного поздно на вечеринку, но это было полезно для меня, так что поехали.
Начиная с .Net 3.0,
FrameworkElement
есть функция MoveFocus, которая помогала мне.источник
Поскольку ни один из приведенных выше ответов не помог мне, а принятый ответ действительно работает только для фокуса клавиатуры, я пришел к следующему подходу:
// Kill logical focus FocusManager.SetFocusedElement(FocusManager.GetFocusScope(textBox), null); // Kill keyboard focus Keyboard.ClearFocus();
Убивает и логику, и фокус клавиатуры.
источник
Вы можете установить фокус на предка, которого можно сфокусировать. Этот код будет работать, даже если текстовое поле находится внутри шаблона без фокусируемых предков внутри того же шаблона:
DependencyObject ancestor = textbox.Parent; while (ancestor != null) { var element = ancestor as UIElement; if (element != null && element.Focusable) { element.Focus(); break; } ancestor = VisualTreeHelper.GetParent(ancestor); }
источник
AFAIK, полностью убрать фокус невозможно. Что-то в вашем окне всегда будет в центре внимания.
источник
В разработке для Windows Phone я просто использовал
Focus()
илиthis.Focus()
в PhoneApplicationPage, и это сработало отлично .источник
Для меня это довольно сложно, особенно при использовании с привязкой LostFocus. Однако мой обходной путь - добавить пустую метку и сосредоточиться на ней.
<Label Name="ResetFocusArea" Focusable="True" FocusVisualStyle="{x:Null}" />
...
OnKeyDown(object sender, RoutedEventArgs e) { //if is Esc ResetFocusArea.Focus(); }
источник
Мой ответ не касается непосредственно вышеупомянутого вопроса, однако я чувствую, что его формулировка превратила его в «Вопрос» о программном избавлении от фокуса. Обычный сценарий, когда это необходимо, - чтобы пользователь мог очистить фокус, щелкнув левой кнопкой мыши фон корневого элемента управления, например окна.
Итак, для этого вы можете создать Attached Behavior, который переключит фокус на динамически созданный элемент управления (в моем случае - пустую метку). Предпочтительно использовать это поведение на элементах самого высокого уровня, таких как окна, поскольку оно выполняет итерацию по дочерним элементам, чтобы найти панель, к которой можно добавить фиктивную метку.
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(); } }
источник