Ответ 1
в .NET Framework 4 просто Keyboard.ClearFocus();
Я хочу добавить к моему WPF TextBox
простое (по крайней мере, я думал, это было) поведение.
Когда пользователь нажимает Escape, я хочу, чтобы TextBox
он редактировал текст, который у него был, когда пользователь начал редактировать, и я хочу удалить фокус из TextBox
.
У меня нет проблем с установкой текста для значения, которое оно имело в начале редактирования.
Проблема заключается в удалении фокуса элемента. Я не хочу переместить фокус на любой другой компонент, я просто хочу, чтобы TextBox
потерял фокус. Должен ли я иметь невидимый элемент для установки фокуса, чтобы мой TextBox
мог потерять фокус?
в .NET Framework 4 просто Keyboard.ClearFocus();
Код, который я использовал:
// 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, которая сделала трюк для меня.
Вы можете установить фокус на фокусируемого предка. Этот код будет работать, даже если текстовое поле находится внутри шаблона без ориентированных предков внутри того же шаблона:
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 Development я просто сделал Focus()
или this.Focus()
в PhoneApplicationPage, и он работал как шарм.
Поскольку ни один из приведенных выше ответов не работал для меня, и принятый ответ работает только для клавиатуры, я пришел к следующему подходу:
// Kill logical focus
FocusManager.SetFocusedElement(FocusManager.GetFocusScope(textBox), null);
// Kill keyboard focus
Keyboard.ClearFocus();
Убивает как логический, так и фокус клавиатуры.
Для меня это довольно сложно, особенно при использовании с привязкой 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();
}
}
Keyboard.ClearFocus();
- путь.