C# WPF 将焦点重置为按钮单击

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2052389/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 23:02:19  来源:igfitidea点击:

WPF Reset Focus on Button Click

c#wpfdata-bindingbuttonfocus

提问by HaxElit

I have a TextBoxand a ToolBarwith a Button. If I'm typing in the TextBoxand I click the ButtonI want the TextBoxto lose Focusso the binding gets updated. I don't want to add a UpdateSourceTrigger=PropertyChangedto my TextBox. But instead when I click on the ButtonI reset Focusto the main window so what ever I'm on loses Focusand updates the bindings.

我有一个TextBoxToolBar一个Button。如果我正在输入TextBox并单击Button我希望TextBox丢失的Focus,则绑定会更新。我不想UpdateSourceTrigger=PropertyChanged在我的TextBox. 但是当我点击Button我重置Focus到主窗口时,我所做的一切都会丢失Focus并更新绑定。

I've tried adding a OnClickto the button with the following, but it doesn't seem to work:

我尝试OnClick使用以下内容向按钮添加 a ,但似乎不起作用:

    private void Button_Click(object sender, RoutedEventArgs e) {
        FocusManager.SetFocusedElement(this, null);
    }

Any tips would be appreciated.

任何提示将不胜感激。

Thanks, Raul

谢谢,劳尔

采纳答案by Ray Burns

The problem is that the toolbar places your button in a different FocusManager.FocusScope. That means that both the Buttonand the TextBoxcan receive logical focus at the same time, each in its own scope. This is normally a good thing, since you usually don't want to lose focus in your main window area when you select menu items and ToolBar buttons, but in your case it is preventing what you are doing from working.

问题在于工具栏将您的按钮放置在不同的FocusManager.FocusScope. 这意味着 theButton和 theTextBox可以同时接收逻辑焦点,每个焦点都在自己的范围内。这通常是一件好事,因为当您选择菜单项和工具栏按钮时,您通常不希望在主窗口区域失去焦点,但在您的情况下,它会阻止您正在执行的操作。

Although you could override the FocusManager.IsFocusScopeproperty on the toolbar and get the effect you want, this is probably not the best plan since it would make all the other toolbar buttons also steal focus from your main window area.

尽管您可以覆盖FocusManager.IsFocusScope工具栏上的属性并获得您想要的效果,但这可能不是最佳计划,因为它会使所有其他工具栏按钮也从您的主窗口区域窃取焦点。

Instead you could use one of several easy solutions:

相反,您可以使用以下几种简单解决方案之一:

  • Put your button outside the Toolbar
  • Add a Focusable="true" control to your main window area and focus it when the button is clicked
  • Manually force the update by calling textBox.GetBindingExpression(TextBox.TextProperty).UpdateSource()
  • Temporarily set Focusable="true" on a control in the main window, set focus to it, then immediately set Focusable="false" again
  • 将您的按钮放在工具栏之外
  • 将 Focusable="true" 控件添加到主窗口区域并在单击按钮时将其聚焦
  • 通过调用手动强制更新 textBox.GetBindingExpression(TextBox.TextProperty).UpdateSource()
  • 在主窗口中的控件上临时设置 Focusable="true",设置焦点,然后立即再次设置 Focusable="false"

回答by Dudu

I encountered a similar issue. I need to unfocus a textbox when enter is pressed. I end up with this code:

我遇到了类似的问题。按下 Enter 时,我需要取消聚焦文本框。我最终得到了这个代码:

var scope = FocusManager.GetFocusScope(elem); // elem is the UIElement to unfocus
FocusManager.SetFocusedElement(scope, null); // remove logical focus
Keyboard.ClearFocus(); // remove keyboard focus

I think it is cleaner than creating dummy controls and it is reusable. I'm not confident with this solution though. But it seems work well.

我认为它比创建虚拟控件更干净,并且可以重复使用。不过,我对这个解决方案没有信心。但它似乎运作良好。