【问题标题】:WPF Reset Focus on Button ClickWPF 在按钮单击时重置焦点
【发布时间】:2011-01-04 08:59:52
【问题描述】:

我有一个TextBox 和一个ToolBar 和一个Button。如果我输入TextBox 并单击Button,我希望TextBox 丢失Focus,以便更新绑定。我不想将UpdateSourceTrigger=PropertyChanged 添加到我的TextBox。但是,当我点击Button 时,我将Focus 重置为主窗口,因此我所使用的任何内容都会丢失Focus 并更新绑定。

我尝试使用以下命令将OnClick 添加到按钮,但它似乎不起作用:

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

任何提示将不胜感激。

谢谢, 劳尔

【问题讨论】:

    标签: c# wpf data-binding button focus


    【解决方案1】:

    我在离开日历时遇到问题,需要单击按钮两次(WPF,.Net 5.0),我尝试了上面建议的一些解决方案,但没有成功,但这有效 - 引用自 Microsoft 网站上的某人:

    “我对这个问题的解决方案是插入到主窗体中,但这可能是矫枉过正。”

    protected override void OnPreviewMouseUp(MouseButtonEventArgs e)
    {
      base.OnPreviewMouseUp(e);
      if (Mouse.Captured is Calendar || Mouse.Captured is System.Windows.Controls.Primitives.CalendarItem)
      {
        Mouse.Capture(null);
      }
    }
    

    【讨论】:

      【解决方案2】:

      我遇到了类似的问题。按下回车键时,我需要取消焦点文本框。我最终得到了这段代码:

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

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

      【讨论】:

      • 这对我有用,因为没有其他方法会强制 DatePicker 在单击工具栏中的保存按钮时解析输入的文本。下面的代码使用视图 (MVVM) 作为 this.owner,从 ViewModel 调用。 var t =(DependencyObject)FocusManager.GetFocusedElement(this.Owner); var scope = FocusManager.GetFocusScope(t); FocusManager.SetFocusedElement(scope, null);
      【解决方案3】:

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

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

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

      • 将按钮放在工具栏之外
      • 将 Focusable="true" 控件添加到您的主窗口区域,并在单击按钮时将其聚焦
      • 通过调用textBox.GetBindingExpression(TextBox.TextProperty).UpdateSource() 手动强制更新
      • 在主窗口中的一个控件上临时设置 Focusable="true",为其设置焦点,然后立即再次设置 Focusable="false"

      【讨论】:

      • 我试过 Keyboard.Focus(mainWindow);但这似乎也没有改变焦点。它保留在文本框或选择的任何元素上。现在我只是明确地将元素强制为 UpdateSource() ,但这似乎不是一个长期可持续的解决方案。我会尝试添加一个幽灵控件来设置焦点。
      • Keyboard.Focus(mainWindow) 仅在 "mainWindow" 是可聚焦的(默认情况下不是)并且与 TextBox 位于同一 FocusScope 时才有效。尝试在与 TextBox 相同的容器中创建一个 Focusable="true" 控件并将其聚焦。另一个控件可以是简单的<Control Focusable="true" IsTabStop="false"/>。由于Control 没有默认模板,它将是不可见的。
      • 感谢您提及FocusManager.IsFocusScope。在我的特定场景中,我想要从我的主窗口区域窃取焦点,所以我只是在我的工具栏上设置了FocusManager.IsFocusScope="False"。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-09
      • 2023-03-25
      • 1970-01-01
      • 2011-11-27
      相关资源
      最近更新 更多