我想为WPF添加一个简单的(至少我以为是)行为TextBox
。
当用户按下Escape键时,我希望TextBox
他正在编辑,以使其具有用户开始编辑时的文本,并且我想从中移除焦点TextBox
。
我将文本设置为编辑开始时的值没有任何问题。
问题是要删除该元素的焦点。我不想将焦点移到任何其他组件,我只是想TextBox
失去焦点。我是否需要一个不可见的元素来设置焦点,以便我TextBox
可以失去焦点?
我想为WPF添加一个简单的(至少我以为是)行为TextBox
。
当用户按下Escape键时,我希望TextBox
他正在编辑,以使其具有用户开始编辑时的文本,并且我想从中移除焦点TextBox
。
我将文本设置为编辑开始时的值没有任何问题。
问题是要删除该元素的焦点。我不想将焦点移到任何其他组件,我只是想TextBox
失去焦点。我是否需要一个不可见的元素来设置焦点,以便我TextBox
可以失去焦点?
Answers:
在.NET Framework 4中 Keyboard.ClearFocus();
Keyboard.ClearFocus()
单击某个位置后从后台运行代码时,ListBox内的AutoCompleteTextBox不会失去焦点。
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函数,该函数为我完成了窍门。
您可以将焦点设置为可聚焦的祖先。即使文本框位于模板内,而同一模板内没有可聚焦祖先,该代码也将起作用:
DependencyObject ancestor = textbox.Parent;
while (ancestor != null)
{
var element = ancestor as UIElement;
if (element != null && element.Focusable)
{
element.Focus();
break;
}
ancestor = VisualTreeHelper.GetParent(ancestor);
}
在Windows Phone开发中,我只是这样做, Focus()
或者this.Focus()
在PhoneApplicationPage中工作时,它就像一个魅力。
我的回答不能直接解决上述问题,但是,我觉得它的措辞已使它成为关于以编程方式摆脱焦点的“问题”。需要此操作的常见方案是用户能够通过左键单击根控件(如窗口)的背景来清除焦点。
因此,要实现此目的,您可以创建一个附加行为,该行为会将焦点切换到动态创建的控件(在我的情况下为空标签)。最好在Windows等最高级别的元素上使用此行为,因为它会遍历其子级以查找可以向其添加虚拟标签的面板。
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();
}
}